All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Thierry Reding" <thierry.reding@kernel.org>
Cc: devicetree@vger.kernel.org, "Heiko Carstens" <hca@linux.ibm.com>,
	conor+dt@kernel.org, "Alexander Gordeev" <agordeev@linux.ibm.com>,
	robh@kernel.org, dri-devel@lists.freedesktop.org,
	linux-s390@vger.kernel.org, "Vasily Gorbik" <gor@linux.ibm.com>
Subject: Re: [PATCH v3 08/11] dma-buf: heaps: Add support for Tegra VPR
Date: Wed, 01 Jul 2026 16:34:27 +0000	[thread overview]
Message-ID: <20260701163428.084CE1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260701-tegra-vpr-v3-8-d80f7b871bb4@nvidia.com>

Thank you for your contribution! Sashiko AI review found 20 potential issue(s) to consider:
- [High] The driver hijacks global system suspend primitives to implement a hardware-specific memory resize operation, causing race conditions and deadlocks.
- [High] Allocated pages are freed using an excessively large size calculated via `get_order(size)`, leading to adjacent active memory being mistakenly cleared.
- [High] The `vpr->lock` mutex is dynamically allocated but never initialized.
- [High] In the chunk recycle loop, the driver uses the wrong loop variable to clear active and dirty bits, corrupting the chunk bitmap state.
- [High] Unchecked access to `dev->driver->pm->freeze` causes a kernel panic if a device has no PM ops.
- [High] Concurrent modification and traversal of the `vpr->devices` list.
- [High] Using `phys_to_page()` on `no-map` reserved memory yields invalid page pointers.
- [High] A race between module initialization and device probing can cause a NULL pointer dereference in `tegra_vpr_device_init`.
- [High] `tegra_vpr_resize` returns success (0) even if freezing a device fails and the hardware VPR is never resized, bypassing memory protections.
- [High] Integer truncation in the `num_pages` calculation allows massive DMA-BUF sizes to be allocated with 0 backing pages, leading to immediate kernel panics when mapped.
- [High] CMA memory is released before the VPR hardware firewall is removed.
- [Medium] The error recovery path in `tegra_vpr_recycle()` fails to restore the `vpr->active` bitmap.
- [Medium] Device node pointers are saved without taking reference counts, leading to UAF and a memory leak of the `/reserved-memory` node.
- [Medium] `tegra_vpr_find_free_region` passes `vpr->num_pages - 1` as the `end_page` boundary, preventing allocation of the last page of the VPR.
- [Medium] `kmalloc_array` is used to allocate an excessively large page pointer array.
- [Medium] Active VPR chunks are not deactivated if `dma_buf_export` fails.
- [Medium] `tegra_vpr_resize` calls `freeze_processes()` but the driver lacks a `CONFIG_FREEZER` or `CONFIG_PM_SLEEP` dependency.
- [Medium] Lockless iteration of `vpr->buffers` in debugfs exposes a TOCTOU list corruption race.
- [Medium] Negative bit shift when `vpr->size` is small, and chunk setup can create 0-sized chunks.
- [Low] Typo in `attach->dev` initialization results in self-assignment of a zero-initialized field.
--

commit 4c286d7ffd5b9cd569447863a311213170bdfb04
Author: Thierry Reding <treding@nvidia.com>
Subject: dma-buf: heaps: Add support for Tegra VPR

This commit exposes the Tegra Video-Protection-Region (VPR) as a DMA heap.
The memory region is dynamically resized by freezing userspace processes and
allocating/freeing chunks via CMA.

> diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig
> index bb729e91545c4..dd6035598d028 100644
> --- a/drivers/dma-buf/heaps/Kconfig
> +++ b/drivers/dma-buf/heaps/Kconfig
[ ... ]
> @@ -20,3 +20,10 @@ config DMABUF_HEAPS_CMA
>  	  Choose this option to enable dma-buf CMA heap. This heap is backed
>  	  by the Contiguous Memory Allocator (CMA). If your system has these
>  	  regions, you should say Y here.
> +
> +config DMABUF_HEAPS_TEGRA_VPR
> +	bool "NVIDIA Tegra Video-Protected-Region DMA-BUF Heap"
> +	depends on DMABUF_HEAPS && DMA_CMA

[Severity: Medium]
Should DMABUF_HEAPS_TEGRA_VPR depend on CONFIG_FREEZER or CONFIG_PM_SLEEP?

Since vpr->use_freezer is true, if CONFIG_FREEZER is disabled,
freeze_processes() evaluates to a static inline function returning -ENOSYS.
This will cause the VPR resize operations to unconditionally fail.

> +	help
> +	  Choose this option to enable Video-Protected-Region (VPR) support on
> +	  a range of NVIDIA Tegra devices.
> diff --git a/drivers/dma-buf/heaps/tegra-vpr.c b/drivers/dma-buf/heaps/tegra-vpr.c
> new file mode 100644
> index 0000000000000..918cf66ec222c
> --- /dev/null
> +++ b/drivers/dma-buf/heaps/tegra-vpr.c
[ ... ]
> +static int tegra_vpr_resize(struct tegra_vpr *vpr)
> +{
> +	struct tegra_vpr_device *node;
> +	phys_addr_t base, size;
> +	int err, status = 0;
> +
> +	err = tegra_vpr_get_extents(vpr, &base, &size);
> +	if (err < 0) {
> +		pr_err("%s(): failed to get VPR extents: %d\n", __func__, err);
> +		return err;
> +	}
> +
> +	if (vpr->use_freezer) {
> +		err = freeze_processes();

[Severity: High]
Is it safe to invoke the global task freezer from within a device driver's
allocation path?

In tegra_vpr_allocate(), mutex_lock(&vpr->lock) is held, which places the
current task in TASK_UNINTERRUPTIBLE. tegra_vpr_resize() then conditionally
calls freeze_processes(). If another userspace task is concurrently waiting
for vpr->lock, it cannot be frozen because it is in an uninterruptible sleep
state, and the freeze operation will time out and fail.

> +		if (err < 0) {
> +			pr_err("%s(): failed to freeze processes: %d\n",
> +			       __func__, err);
> +			return err;
> +		}
> +	}
> +
> +	list_for_each_entry(node, &vpr->devices, node) {

[Severity: High]
Are the vpr->devices list modifications protected against concurrent
traversal?

tegra_vpr_device_init() and tegra_vpr_device_release() modify the list
without holding vpr->lock, while this traversal relies on the lock. If a
device binds or unbinds while a VPR resize is active, the list pointers
could become corrupted during the traversal.

> +		err = pm_generic_freeze(node->dev);
> +		if (err < 0) {
> +			pr_err("failed to runtime suspend %s: %d\n",
> +			       dev_name(node->dev), err);
> +			goto thaw;

[Severity: High]
Does this error path inadvertently return success?

The status variable is initialized to 0, and if pm_generic_freeze() fails,
the code jumps to the thaw label without updating status. The function then
returns 0, falsely indicating that the hardware VPR was successfully resized,
potentially compromising memory protections.

> +		}
> +	}
[ ... ]
> +static int tegra_vpr_find_free_region_in_range(struct tegra_vpr *vpr,
> +					       unsigned int start_page,
> +					       unsigned int end_page,
> +					       unsigned int num_pages,
> +					       unsigned int align)
> +{
> +	unsigned int pos, next = ALIGN(start_page, align);
> +
> +	/* Scan through aligned positions, trying to allocate at each one */
> +	for (pos = next; pos + num_pages <= end_page; pos = next) {

[Severity: Medium]
Could this prevent the allocation of the final page of the VPR?

tegra_vpr_find_free_region() passes vpr->num_pages - 1 as the end_page
parameter. This loop condition treats end_page as an exclusive boundary.
If attempting to allocate a buffer right at the end of the VPR, this
boundary check will evaluate to false and fail the allocation.

> +		next = find_next_bit(vpr->bitmap, pos + num_pages, pos);
[ ... ]
> +static struct tegra_vpr_buffer *
> +tegra_vpr_buffer_allocate(struct tegra_vpr *vpr, size_t size)
> +{
> +	unsigned int num_pages = size >> PAGE_SHIFT;

[Severity: High]
Can the 64-bit size parameter overflow the 32-bit unsigned int num_pages?

Shifting a massive size by PAGE_SHIFT could result in a value that truncates
to 0 in num_pages. This would cause kmalloc_array(0) to return ZERO_SIZE_PTR,
which could lead to an immediate kernel panic when the buffer is later mapped.

> +	unsigned int order = get_order(size);
> +	struct tegra_vpr_buffer *buffer;
> +	unsigned long first, last;
> +	int pageno, err;
> +	pgoff_t i;
[ ... ]
> +	buffer->pages = kmalloc_array(buffer->num_pages,
> +				      sizeof(*buffer->pages),
> +				      GFP_KERNEL);

[Severity: Medium]
Will this order-10 contiguous allocation reliably succeed on a heavily
utilized system?

If the VPR is sized for multi-gigabyte video frames (e.g., a 2 GiB allocation
requires 524,288 pages), kmalloc_array() will require multiple megabytes of
contiguous physical memory. This is highly likely to fail due to fragmentation.
Would kvmalloc_array() be more appropriate here?

> +	if (!buffer->pages) {
> +		err = -ENOMEM;
> +		goto free;
> +	}
[ ... ]
> +static void tegra_vpr_buffer_release(struct tegra_vpr_buffer *buffer)
> +{
> +	struct tegra_vpr *vpr = buffer->vpr;
> +	struct tegra_vpr_buffer *entry;
> +	unsigned long first, last;
> +	unsigned int i;
[ ... ]
> +	bitmap_release_region(vpr->bitmap, buffer->pageno, buffer->order);

[Severity: High]
Does this logic mistakenly clear adjacent active memory?

In tegra_vpr_buffer_allocate(), the allocation sets exactly num_pages bits
in vpr->bitmap. However, here it clears bits using buffer->order which is
calculated as get_order(size). Since get_order() rounds up to the next power
of two, non-power-of-two sizes will cause too many bits to be released
(e.g., a 5-page allocation sets 5 bits but order 3 clears 8 bits). This could
mark adjacent pages belonging to other active allocations as free, leading
to reallocation and data corruption.

> +	list_del(&buffer->list);
> +	kfree(buffer->pages);
> +	kfree(buffer);
[ ... ]
> +static int tegra_vpr_attach(struct dma_buf *buf,
> +			    struct dma_buf_attachment *attachment)
> +{
> +	struct tegra_vpr_buffer *buffer = buf->priv;
> +	struct tegra_vpr_attachment *attach;
> +	int err;
> +
> +	attach = kzalloc_obj(*attach, GFP_KERNEL);
> +	if (!attach)
> +		return -ENOMEM;
> +
> +	err = sg_alloc_table_from_pages(&attach->sgt, buffer->pages,
> +					buffer->num_pages, 0, buffer->size,
> +					GFP_KERNEL);
> +	if (err < 0)
> +		goto free;
> +
> +	attach->dev = attach->dev;

[Severity: Low]
Is this field meant to be initialized from attachment->dev?

As written, it assigns the zero-allocated field back to itself, leaving
attach->dev uninitialized.

> +	INIT_LIST_HEAD(&attach->list);
> +	attachment->priv = attach;
[ ... ]
> +static void tegra_vpr_recycle(struct tegra_vpr *vpr)
> +{
> +	DECLARE_BITMAP(dirty, vpr->num_chunks);
> +	unsigned int i;
> +	int err;
> +
> +	bitmap_zero(dirty, vpr->num_chunks);
> +
> +	/*
> +	 * Deactivate any unused chunks from the bottom...
> +	 */
> +	for (i = 0; i < vpr->num_chunks; i++) {
> +		struct tegra_vpr_chunk *chunk = &vpr->chunks[i];
> +
> +		if (!chunk->active)
> +			continue;
> +
> +		if (chunk->num_buffers > 0)
> +			break;
> +
> +		err = tegra_vpr_chunk_deactivate(chunk);

[Severity: High]
Is the CMA memory released back to the general pool before the VPR hardware
firewall is removed?

tegra_vpr_chunk_deactivate() immediately calls cma_release(), making the
memory available to other subsystems. The firewall isn't removed until
tegra_vpr_resize() is called afterward. Any CPU access to the newly
re-allocated memory before the firewall is disabled could cause a hardware
bus error or CPU crash.

> +		if (err < 0)
> +			pr_err("failed to deactivate chunk #%u\n", i);
> +		else {
> +			clear_bit(i, vpr->active);
> +			set_bit(i, dirty);
> +		}
> +	}
> +
> +	/*
> +	 * ... and the top.
> +	 */
> +	for (i = 0; i < vpr->num_chunks; i++) {
> +		unsigned int index = vpr->num_chunks - i - 1;
> +		struct tegra_vpr_chunk *chunk = &vpr->chunks[index];
> +
> +		if (!chunk->active)
> +			continue;
> +
> +		if (chunk->num_buffers > 0)
> +			break;
> +
> +		err = tegra_vpr_chunk_deactivate(chunk);
> +		if (err < 0)
> +			pr_err("failed to deactivate chunk #%u\n", index);
> +		else {
> +			clear_bit(i, vpr->active);

[Severity: High]
Could this loop corrupt the chunk bitmap state?

The top chunk loop iterates over the chunks from the top down using the
calculated index (vpr->num_chunks - i - 1), but when modifying the bitmap,
it clears bit i instead of the calculated index. This could deactivate the
top chunk in hardware but mark the bottom chunk as inactive in the software
bitmap.

> +			set_bit(i, dirty);
> +		}
> +	}
[ ... ]
> +activate:
> +	for_each_set_bit(i, dirty, vpr->num_chunks) {
> +		err = tegra_vpr_chunk_activate(&vpr->chunks[i]);

[Severity: Medium]
Should this error recovery path also restore the bit in vpr->active?

If tegra_vpr_resize() fails, the code jumps here and successfully calls
tegra_vpr_chunk_activate(), but it doesn't set the bit in vpr->active.
Since the bit was cleared in the deactivation loop, the software state
will indicate the chunk is free, breaking internal tracking.

> +		if (WARN_ON(err < 0))
> +			pr_err("failed to activate chunk #%u: %d\n", i, err);
> +	}
> +}
[ ... ]
> +static struct dma_buf *tegra_vpr_allocate(struct dma_heap *heap,
> +					  unsigned long len, u32 fd_flags,
> +					  u64 heap_flags)
> +{
> +	struct tegra_vpr *vpr = dma_heap_get_drvdata(heap);
> +	struct tegra_vpr_buffer *buffer, *entry;
> +	size_t size = ALIGN(len, vpr->align);
> +	DEFINE_DMA_BUF_EXPORT_INFO(export);
> +	struct dma_buf *buf;
> +
> +	mutex_lock(&vpr->lock);

[Severity: High]
Could the uninitialized vpr->lock cause a system crash?

The tegra_vpr structure is allocated using kzalloc_obj(), which
zero-initializes the memory, but mutex_init(&vpr->lock) is never called.
When this function attempts to acquire the lock, it interacts with an
uninitialized mutex, which can trigger warnings or a kernel panic.

> +
> +	buffer = tegra_vpr_buffer_allocate(vpr, size);
[ ... ]
> +	buf = dma_buf_export(&export);
> +	if (IS_ERR(buf))
> +		tegra_vpr_buffer_release(buffer);

[Severity: Medium]
Should the active VPR chunks be deactivated if dma_buf_export() fails?

tegra_vpr_buffer_release() decrements the chunk use counts but does not
deactivate the chunks. A missing call to tegra_vpr_recycle() could mean
chunks successfully activated during this allocation attempt remain pinned
in CMA indefinitely.

> +
> +	mutex_unlock(&vpr->lock);
> +	return buf;
> +}
> +
> +static void tegra_vpr_debugfs_show_buffers(struct tegra_vpr *vpr,
> +					   struct seq_file *s)
> +{
> +	struct tegra_vpr_buffer *buffer;
> +	char buf[16];
> +
> +	list_for_each_entry(buffer, &vpr->buffers, list) {

[Severity: Medium]
Is it safe to traverse the shared vpr->buffers list without holding vpr->lock?

Concurrent buffer allocations or releases could modify the list pointers
mid-traversal, potentially causing a kernel panic when reading the debugfs
node.

> +		string_get_size(buffer->size, 1, STRING_UNITS_2, buf,
> +				sizeof(buf));
> +		seq_printf(s, "  %pap-%pap (%s)\n", &buffer->start,
> +			   &buffer->limit, buf);
> +
> +	}
> +}
[ ... ]
> +static int tegra_vpr_setup_chunks(struct tegra_vpr *vpr, const char *name)
> +{
> +	phys_addr_t start, limit;
> +	unsigned int order, i;
> +	size_t max_size;
> +	int err;
> +
> +	/* This seems a reasonable value, so hard-code this for now. */
> +	vpr->num_chunks = 4;
> +
> +	vpr->chunks = kcalloc(vpr->num_chunks, sizeof(*vpr->chunks),
> +			      GFP_KERNEL);
> +	if (!vpr->chunks)
> +		return -ENOMEM;
> +
> +	max_size = PAGE_SIZE << (get_order(vpr->size) - ilog2(vpr->num_chunks));

[Severity: Medium]
Could this bit shift result in a negative shift amount?

If the device tree specifies a small VPR size, get_order(vpr->size) might
be 0, and subtracting ilog2(vpr->num_chunks) (e.g., 2) would result in -2.
Shifting PAGE_SIZE by a negative amount causes undefined behavior.

> +	order = get_order(vpr->align);
[ ... ]
> +static int __init tegra_vpr_add_heap(struct reserved_mem *rmem,
> +				     struct device_node *np)
> +{
> +	struct dma_heap_export_info info = {};
> +	unsigned long first, last;
> +	struct dma_heap *heap;
> +	struct tegra_vpr *vpr;
> +	int err;
> +
> +	vpr = kzalloc_obj(*vpr, GFP_KERNEL);
> +	if (!vpr)
> +		return -ENOMEM;
> +
> +	INIT_LIST_HEAD(&vpr->buffers);
> +	INIT_LIST_HEAD(&vpr->devices);
> +	vpr->resizable = !of_property_read_bool(np, "no-map");
> +	vpr->use_freezer = true;
> +	vpr->dev_node = np;

[Severity: Medium]
Does this code leak the device node reference?

When storing the child node pointer in vpr->dev_node, should it be acquiring
a reference with of_node_get()? The scoped loop in tegra_vpr_init() will drop
its reference when it finishes, which could leave a dangling pointer here.

> +	vpr->align = PAGE_SIZE;
> +	vpr->base = rmem->base;
> +	vpr->size = rmem->size;
> +
> +	/* common setup */
> +	vpr->start_page = phys_to_page(vpr->base);

[Severity: High]
Can phys_to_page() safely be used if the VPR device tree node specifies no-map?

If the memory is removed from the direct mapping, there is no valid struct
page array associated with it. Calling phys_to_page() here and later
dereferencing these page pointers in tegra_vpr_attach() via
sg_alloc_table_from_pages() could cause a system crash.

> +	vpr->num_pages = vpr->size >> PAGE_SHIFT;
[ ... ]
> +static int __init tegra_vpr_init(void)
> +{
> +	const char *compatible = "nvidia,tegra-video-protection-region";
> +	struct device_node *parent;
> +	struct reserved_mem *rmem;
> +	int err;
> +
> +	parent = of_find_node_by_path("/reserved-memory");

[Severity: Medium]
Does this code leak the device node reference?

of_find_node_by_path() increments the reference count for the
/reserved-memory node, but there doesn't seem to be a matching of_node_put()
call.

> +	if (!parent)
> +		return 0;
[ ... ]
> +static int tegra_vpr_device_init(struct reserved_mem *rmem, struct device *dev)
> +{
> +	struct dma_heap *heap = rmem->priv;
> +	struct tegra_vpr *vpr = dma_heap_get_drvdata(heap);

[Severity: High]
Could a hardware device probing before the module initialization runs cause
a NULL pointer dereference?

tegra_vpr_rmem_ops is registered early via RESERVEDMEM_OF_DECLARE. If a
device probes before tegra_vpr_init() executes, tegra_vpr_device_init() will
be called while rmem->priv is still NULL, causing dma_heap_get_drvdata() to
dereference a NULL pointer.

> +	struct tegra_vpr_device *node;
> +
> +	if (!dev->driver->pm->freeze || !dev->driver->pm->thaw)

[Severity: High]
Can this unconditionally dereference a NULL pointer?

If the device's driver does not provide PM operations (dev->driver->pm is
NULL), this check will cause a kernel panic during device probe.

> +		return -EINVAL;
> +
> +	node = kzalloc_obj(*node, GFP_KERNEL);
> +	if (!node)
> +		return -ENOMEM;
> +
> +	INIT_LIST_HEAD(&node->node);
> +	node->dev = dev;
> +
> +	list_add_tail(&node->node, &vpr->devices);
> +
> +	return 0;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260701-tegra-vpr-v3-0-d80f7b871bb4@nvidia.com?part=8

  reply	other threads:[~2026-07-01 16:34 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-01 16:08 [PATCH v3 00/11] dma-buf: heaps: Add support for Tegra VPR Thierry Reding
2026-07-01 16:08 ` [PATCH v3 01/11] dt-bindings: reserved-memory: Document " Thierry Reding
2026-07-01 16:15   ` sashiko-bot
2026-07-01 19:53   ` Rob Herring (Arm)
2026-07-02 12:58     ` Thierry Reding
2026-07-01 16:08 ` [PATCH v3 02/11] dt-bindings: display: tegra: Document memory regions Thierry Reding
2026-07-01 16:13   ` sashiko-bot
2026-07-01 19:53   ` Rob Herring (Arm)
2026-07-02 13:47     ` Thierry Reding
2026-07-01 16:08 ` [PATCH v3 03/11] dt-bindings: gpu: host1x: Document memory-regions for NVDEC Thierry Reding
2026-07-01 16:16   ` sashiko-bot
2026-07-01 16:08 ` [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal() Thierry Reding
2026-07-01 16:23   ` sashiko-bot
2026-07-02  9:18   ` Will Deacon
2026-07-02 13:46     ` Thierry Reding
2026-07-02 16:41       ` Thierry Reding
2026-07-03 17:13         ` Will Deacon
2026-07-06 13:49           ` Thierry Reding
2026-07-07 11:27             ` Will Deacon
2026-07-07 13:17               ` Robin Murphy
2026-07-07 13:36                 ` Mike Rapoport
2026-07-07 12:15             ` Robin Murphy
2026-07-01 16:08 ` [PATCH v3 05/11] bitmap: Add bitmap_allocate() function Thierry Reding
2026-07-01 16:08 ` [PATCH v3 06/11] mm/cma: Allow dynamically creating CMA areas Thierry Reding
2026-07-01 16:26   ` sashiko-bot
2026-07-03 18:29   ` David Hildenbrand (Arm)
2026-07-07 10:02   ` Marek Szyprowski
2026-07-01 16:08 ` [PATCH v3 07/11] dma-buf: heaps: Add debugfs support Thierry Reding
2026-07-01 16:27   ` sashiko-bot
2026-07-03 12:14   ` Maxime Ripard
2026-07-01 16:08 ` [PATCH v3 08/11] dma-buf: heaps: Add support for Tegra VPR Thierry Reding
2026-07-01 16:34   ` sashiko-bot [this message]
2026-07-01 16:08 ` [PATCH v3 09/11] arm64: tegra: Add VPR placeholder node on Tegra234 Thierry Reding
2026-07-01 16:08 ` [PATCH v3 10/11] arm64: tegra: Hook up VPR to host1x Thierry Reding
2026-07-01 22:46   ` sashiko-bot
2026-07-01 16:08 ` [PATCH v3 11/11] arm64: tegra: Add VPR placeholder node on Tegra264 Thierry Reding
2026-07-01 16:32   ` 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=20260701163428.084CE1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=linux-s390@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=thierry.reding@kernel.org \
    /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.