All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "David Woodhouse" <dwmw2@infradead.org>
Cc: kvm@vger.kernel.org, dri-devel@lists.freedesktop.org,
	media-ci@linuxtv.org
Subject: Re: [RFC PATCH 11/11] samples/kvm, selftests/kvm: Allow the gmem_provider NVMe DMA test on arm64
Date: Thu, 16 Jul 2026 15:54:06 +0000	[thread overview]
Message-ID: <20260716155406.A9E961F000E9@smtp.kernel.org> (raw)
In-Reply-To: <a8a919d0b2884e4169a6951ba11152b3c8b1d07d.1784194290.git.dwmw@amazon.co.uk>

Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [Critical] The gmem_provider sample module blindly trusts the `setup.kvm_fd` file descriptor, leading to type confusion and local privilege escalation.
- [High] A data race on the `info->kvm` pointer between `gmem_bind` and `gmem_fd_ioctl` allows a concurrent binding to drop the VM reference while it is actively being used, leading to a Use-After-Free.
- [Medium] The NVMe DMA selftest hardcodes the Amazon PCI Vendor ID (0x1d0f), causing it to fail on non-Amazon NVMe devices.
- [Medium] The selftest implicitly assumes a 4KB system page size, causing IOMMU mapping failures on architectures with larger page sizes.
- [Medium] The selftest bypasses architecture-specific I/O accessors and omits mandatory memory barriers, causing data races on weakly-ordered architectures.
- [Medium] The selftest performs raw, native-endian memory accesses on strictly little-endian PCI configuration space and NVMe registers, causing corruption on big-endian architectures.
--

--- Patch [11]: [RFC PATCH 11/11] samples/kvm, selftests/kvm: Allow the gmem_provider NVMe DMA test on arm64 ---
commit fc0ebbb277714921db32af720eb2c5783d061ea0
Author: David Woodhouse <dwmw@amazon.co.uk>

samples/kvm, selftests/kvm: Allow the gmem_provider NVMe DMA test on arm64

The sample provider and the NVMe DMA selftest have no x86 specifics.
Drop the X86_64 gate on the sample's Kconfig (arm64 also has
KVM_GUEST_MEMFD; the SEV RMP reset is already guarded by
CONFIG_AMD_MEM_ENCRYPT) and move the NVMe DMA selftest from
TEST_GEN_PROGS_x86 to TEST_GEN_PROGS_COMMON so it also builds on
architectures with an IOMMU (arm64 SMMU-v3, ...).

> diff --git a/samples/Kconfig b/samples/Kconfig
> index 3482659638b5b..d26a03dea0728 100644
> --- a/samples/Kconfig
> +++ b/samples/Kconfig
> @@ -328,7 +328,7 @@ source "samples/damon/Kconfig"
>  
>  config SAMPLE_KVM_GMEM_PROVIDER
>  	tristate "Build sample guest_memfd provider -- loadable module only"
> -	depends on KVM_GUEST_MEMFD && X86_64 && m
> +	depends on KVM_GUEST_MEMFD && (X86_64 || ARM64) && m

[Severity: Critical]
Is it safe to blindly trust the kvm_fd here?

In gmem_ctl_ioctl(), the user-provided setup.kvm_fd is resolved and used
like this:

samples/kvm/gmem_provider.c:gmem_ctl_ioctl() {
    ...
	kvm_file = fget(setup.kvm_fd);
	if (!kvm_file)
		return -EBADF;
	kvm = kvm_file->private_data;
	if (!kvm) {
		fput(kvm_file);
		return -EINVAL;
	}
	kvm_get_kvm(kvm);
    ...
}

If a user passes an arbitrary file descriptor, it could lead to type confusion
since we don't verify the file's operations before extracting private_data and
performing an out-of-bounds refcount_inc(&kvm->users_count).

[Severity: High]
Can gmem_fd_ioctl() safely use info->kvm without synchronization?

In gmem_fd_ioctl(), info->kvm is used without holding a lock:

samples/kvm/gmem_provider.c:gmem_fd_ioctl() {
    ...
		if (info->kvm)
			kvm_gmem_invalidate_range(info->kvm,
				info->base_gfn + start_index - info->pgoff,
				info->base_gfn + end_index - info->pgoff);
    ...
}

Concurrently, gmem_bind() can swap info->kvm and drop the underlying
reference:

samples/kvm/gmem_provider.c:gmem_bind() {
    ...
	if (info->kvm != kvm) {
		kvm_get_kvm(kvm);
		if (info->kvm)
			kvm_put_kvm(info->kvm);
		info->kvm = kvm;
	}
    ...
}

Could this concurrent binding drop the VM reference to zero while it is being
accessed by the ioctl, leading to a use-after-free?

[ ... ]

> diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
> index 7f46843e7428f..12004a487c326 100644
> --- a/tools/testing/selftests/kvm/Makefile.kvm
> +++ b/tools/testing/selftests/kvm/Makefile.kvm
> @@ -58,6 +58,7 @@ TEST_PROGS_x86 += x86/nx_huge_pages_test.sh
>  # Compiled test targets valid on all architectures with libkvm support
>  TEST_GEN_PROGS_COMMON = demand_paging_test
>  TEST_GEN_PROGS_COMMON += dirty_log_test
> +TEST_GEN_PROGS_COMMON += gmem_provider_nvme_dma_test

[Severity: Medium]
Will this regression cause the test to fail on host hardware that doesn't use
an Amazon NVMe device?

The test hardcodes the Amazon PCI Vendor ID:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:main() {
    ...
		TEST_ASSERT(vid == 0x1d0f,
			    "unexpected VID 0x%04x in provider region -- Identify DMA landed elsewhere?\n"
    ...
}

Should the expected VID be read dynamically from offset 0x00 instead?

[Severity: Medium]
Does the implicit 4KB system page size assumption introduce a regression on
architectures that commonly use larger page sizes, such as arm64?

The test uses hardcoded 4KB offsets and lengths for IOMMU mapping:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:main() {
    ...
	TEST_ASSERT(!ioas_map_user(iommufd_fd, alloc.out_ioas_id, sq_buf, IOVA_SQ, 0x1000),
		    "IOAS_MAP(sq) errno=%d", errno);
	TEST_ASSERT(!ioas_map_user(iommufd_fd, alloc.out_ioas_id, cq_buf, IOVA_CQ, 0x1000),
		    "IOAS_MAP(cq) errno=%d", errno);
    ...
}

Since iommufd requires mapping lengths and IOVAs to be aligned to the system
page size, won't this fail on kernels running with 16KB or 64KB page sizes?

[Severity: Medium]
Can a data race occur on weakly-ordered architectures without memory barriers?

The custom MMIO accessors use plain volatile writes:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:wr32() {
    ...
static void     wr32(void *b, uint32_t o, uint32_t v) { *(volatile uint32_t *)((char *)b + o) = v; }
    ...
}

When ringing the doorbell:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:main() {
    ...
	/* Ring SQ0 tail doorbell. */
	wr32(bar, NVME_SQ0TDBL, 1);
    ...
}

Without an explicit memory barrier, is the CPU free to reorder the MMIO write
to the doorbell ahead of the normal RAM writes to the Submission Queue Entry?

[Severity: Medium]
Does this code corrupt device state on big-endian architectures?

Since the test is now built for all architectures, it will run on big-endian
systems. However, the test uses native-endian assignments to interact with
little-endian PCI configuration space and NVMe registers:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:main() {
    ...
	TEST_ASSERT(pread(vfio_fd, &pci_cmd, 2, cfg_off + 0x04) == 2, "cfg CMD read");
	pci_cmd |= 0x0006;
	TEST_ASSERT(pwrite(vfio_fd, &pci_cmd, 2, cfg_off + 0x04) == 2, "cfg CMD write");
    ...
}

And for the NVMe SQE:

tools/testing/selftests/kvm/gmem_provider_nvme_dma_test.c:main() {
    ...
		s[0]  = 0x00010006;	/* CID=1 << 16 | OPC=Identify */
    ...
}

Will these direct native-endian accesses produce byte-swapped data on
big-endian CPUs and cause the test to fail?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/f09647f427565c1789a6979470045aab78661563.1784194290.git.dwmw@amazon.co.uk?part=11

  reply	other threads:[~2026-07-16 15:54 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16  9:31 [RFC PATCH 00/11] KVM: Allow alternative providers of guest_memfd backed by PFNMAP memory David Woodhouse
2026-07-16  9:31 ` [RFC PATCH 01/11] KVM: selftests: sev_smoke_test: Only run VM types the host offers David Woodhouse
2026-07-16  9:31   ` [RFC PATCH 02/11] KVM: selftests: sev_init2_tests: Derive SEV availability from KVM David Woodhouse
2026-07-16  9:31   ` [RFC PATCH 03/11] KVM: SEV: Remove struct page dependency from SNP gmem paths David Woodhouse
2026-07-16 15:30     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 04/11] KVM: guest_memfd: Introduce guest memory ops and route native gmem through them David Woodhouse
2026-07-16 15:30     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 05/11] iommufd: Look up private-interconnect phys via exporter symbols David Woodhouse
2026-07-16 15:33     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 06/11] iommufd: Plumb dma-buf memory-type (RAM vs MMIO) through the phys map David Woodhouse
2026-07-16 15:41     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 07/11] KVM: guest_memfd: Add ops-driven page revocation David Woodhouse
2026-07-16 15:42     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 08/11] samples/kvm: Add guest_memfd backing sample David Woodhouse
2026-07-16 15:53     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 09/11] selftests/kvm: gmem_provider KVM-only tests David Woodhouse
2026-07-16 15:46     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 10/11] selftests/kvm: gmem_provider iommufd tests David Woodhouse
2026-07-16 15:48     ` sashiko-bot
2026-07-16  9:31   ` [RFC PATCH 11/11] samples/kvm, selftests/kvm: Allow the gmem_provider NVMe DMA test on arm64 David Woodhouse
2026-07-16 15:54     ` sashiko-bot [this message]
2026-07-16 15:31   ` [RFC PATCH 01/11] KVM: selftests: sev_smoke_test: Only run VM types the host offers sashiko-bot

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=20260716155406.A9E961F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=dwmw2@infradead.org \
    --cc=kvm@vger.kernel.org \
    --cc=media-ci@linuxtv.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.