Devicetree
 help / color / mirror / Atom feed
* [PATCH v2 0/4] Support partitioned Host1x
@ 2026-07-02  4:10 Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional Mikko Perttunen
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Mikko Perttunen @ 2026-07-02  4:10 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

The resources (channels, syncpoints) provided by Host1x can be split 
into multiple independent partitions similar to e.g. PCIe VFs, which can 
be assigned to virtual machines, non-CPU embedded controllers, or other 
bus masters.

Each partition has its own MMIO register region and interrupts through 
which the set of channels and syncpoints assigned to it can be accessed. 
This set is configured via the hypervisor MMIO region earlier during 
boot.

This series adds device tree bindings and support in the driver to 
function when Host1x has been partitioned in this way, by making the 
driver work without access to the hypervisor region and with a limited 
set of channels and syncpoints.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
Changes in v2:
- Updated commit messages to clarify software view of registers
- Minor rewording of schema description for channels/syncpoints
  properties
- Rebased on v7.2-rc1
- Link to v1: https://patch.msgid.link/20260622-host1x-nohv-v1-0-65bc682a617f@nvidia.com

---
Mikko Perttunen (4):
      dt-bindings: display: tegra: Make non-vm registers optional
      dt-bindings: display: tegra: Add channel/syncpoint range properties
      gpu: host1x: Support running without hv/common registers
      gpu: host1x: Allow limiting usable channel and syncpoint ranges

 .../display/tegra/nvidia,tegra20-host1x.yaml       | 52 ++++++++++++++++------
 drivers/gpu/host1x/channel.c                       |  6 +--
 drivers/gpu/host1x/dev.c                           | 52 +++++++++++++++++++---
 drivers/gpu/host1x/dev.h                           |  3 ++
 drivers/gpu/host1x/hw/cdma_hw.c                    |  3 ++
 drivers/gpu/host1x/hw/debug_hw_1x06.c              |  3 ++
 drivers/gpu/host1x/syncpt.c                        | 21 +++++----
 7 files changed, 110 insertions(+), 30 deletions(-)
---
base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
change-id: 20250919-host1x-nohv-071ed7c6ac4f


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional
  2026-07-02  4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
@ 2026-07-02  4:10 ` Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 2/4] dt-bindings: display: tegra: Add channel/syncpoint range properties Mikko Perttunen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Mikko Perttunen @ 2026-07-02  4:10 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

The hypervisor and common register regions are not always available to
the software -- usually when a separate hypervisor keeps ownership of
them and only passes through the vm register region to a virtual
machine.

Adjust the bindings to make these regions optional to allow describing
the situation in device trees for such virtual machines et cetera.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 .../display/tegra/nvidia,tegra20-host1x.yaml       | 40 ++++++++++++++--------
 1 file changed, 26 insertions(+), 14 deletions(-)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
index 3563378a01af..ffd0ed857d28 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
@@ -145,14 +145,20 @@ allOf:
     then:
       properties:
         reg-names:
-          items:
-            - const: hypervisor
-            - const: vm
+          oneOf:
+            - items:
+                - const: hypervisor
+                - const: vm
+            - items:
+                - const: vm
 
         reg:
-          items:
-            - description: region used by the hypervisor
-            - description: region assigned to the virtual machine
+          oneOf:
+            - items:
+                - description: region used by the hypervisor
+                - description: region assigned to the virtual machine
+            - items:
+                - description: region assigned to the virtual machine
 
         resets:
           maxItems: 1
@@ -195,16 +201,22 @@ allOf:
     then:
       properties:
         reg-names:
-          items:
-            - const: common
-            - const: hypervisor
-            - const: vm
+          oneOf:
+            - items:
+                - const: common
+                - const: hypervisor
+                - const: vm
+            - items:
+                - const: vm
 
         reg:
-          items:
-            - description: region used by host1x server
-            - description: region used by the hypervisor
-            - description: region assigned to the virtual machine
+          oneOf:
+            - items:
+                - description: region used by host1x server
+                - description: region used by the hypervisor
+                - description: region assigned to the virtual machine
+            - items:
+                - description: region assigned to the virtual machine
 
         interrupts:
           items:

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/4] dt-bindings: display: tegra: Add channel/syncpoint range properties
  2026-07-02  4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional Mikko Perttunen
@ 2026-07-02  4:10 ` Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 3/4] gpu: host1x: Support running without hv/common registers Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges Mikko Perttunen
  3 siblings, 0 replies; 6+ messages in thread
From: Mikko Perttunen @ 2026-07-02  4:10 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

All of the resources implemented by Host1x hardware may not be available
to the software in cases where those resources are assigned to other vm
partitions through the hypervisor register region.

Add properties nvidia,channels and nvidia,syncpoints to specify the
range of resources that are accessible by this partition / virtual
machine.

The hypervisor or bootloader that configures the partitioning in the
hypervisor register region is responsible for updating the values of
these properties in accordance to the configuration.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 .../bindings/display/tegra/nvidia,tegra20-host1x.yaml        | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
index ffd0ed857d28..a6bef28e8559 100644
--- a/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
+++ b/Documentation/devicetree/bindings/display/tegra/nvidia,tegra20-host1x.yaml
@@ -96,6 +96,18 @@ properties:
     items:
       - description: phandle to the HEG or core power domain
 
+  nvidia,channels:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 2
+    maxItems: 2
+    description: Describes range of usable Host1x channels as a <base count> tuple.
+
+  nvidia,syncpoints:
+    $ref: /schemas/types.yaml#/definitions/uint32-array
+    minItems: 2
+    maxItems: 2
+    description: Describes range of writable Host1x syncpoints as a <base count> tuple.
+
 required:
   - compatible
   - interrupts

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/4] gpu: host1x: Support running without hv/common registers
  2026-07-02  4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 2/4] dt-bindings: display: tegra: Add channel/syncpoint range properties Mikko Perttunen
@ 2026-07-02  4:10 ` Mikko Perttunen
  2026-07-02  4:10 ` [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges Mikko Perttunen
  3 siblings, 0 replies; 6+ messages in thread
From: Mikko Perttunen @ 2026-07-02  4:10 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Host1x can be used without access to the hypervisor or common regions
when they are configured by other components in the system. Add support
for running without access to them.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/host1x/dev.c              | 15 ++++++++++-----
 drivers/gpu/host1x/hw/cdma_hw.c       |  3 +++
 drivers/gpu/host1x/hw/debug_hw_1x06.c |  3 +++
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 3f475f0e6545..545fa2e3f180 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -305,7 +305,7 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
 	const struct host1x_info *info = host->info;
 	unsigned int i;
 
-	if (!info->has_hypervisor)
+	if (!host->hv_regs)
 		return;
 
 	for (i = 0; i < info->num_sid_entries; i++) {
@@ -532,15 +532,20 @@ static int host1x_probe(struct platform_device *pdev)
 	host->info = of_device_get_match_data(&pdev->dev);
 
 	if (host->info->has_hypervisor) {
+		struct resource *res;
+
 		host->regs = devm_platform_ioremap_resource_byname(pdev, "vm");
 		if (IS_ERR(host->regs))
 			return PTR_ERR(host->regs);
 
-		host->hv_regs = devm_platform_ioremap_resource_byname(pdev, "hypervisor");
-		if (IS_ERR(host->hv_regs))
-			return PTR_ERR(host->hv_regs);
+		res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hypervisor");
+		if (res) {
+			host->hv_regs = devm_ioremap_resource(&pdev->dev, res);
+			if (IS_ERR(host->hv_regs))
+				return PTR_ERR(host->hv_regs);
+		}
 
-		if (host->info->has_common) {
+		if (res && host->info->has_common) {
 			host->common_regs = devm_platform_ioremap_resource_byname(pdev, "common");
 			if (IS_ERR(host->common_regs))
 				return PTR_ERR(host->common_regs);
diff --git a/drivers/gpu/host1x/hw/cdma_hw.c b/drivers/gpu/host1x/hw/cdma_hw.c
index 3f3f0018eee0..85f7e5633555 100644
--- a/drivers/gpu/host1x/hw/cdma_hw.c
+++ b/drivers/gpu/host1x/hw/cdma_hw.c
@@ -253,6 +253,9 @@ static void timeout_release_mlock(struct host1x_cdma *cdma)
 	struct host1x *host1x = cdma_to_host1x(cdma);
 	u32 offset;
 
+	if (!host1x->common_regs)
+		return;
+
 	switch (ch->client->class) {
 	case HOST1X_CLASS_NVJPG1:
 		offset = HOST1X_COMMON_NVJPG1_MLOCK;
diff --git a/drivers/gpu/host1x/hw/debug_hw_1x06.c b/drivers/gpu/host1x/hw/debug_hw_1x06.c
index 9d0667879a19..324e76436f7b 100644
--- a/drivers/gpu/host1x/hw/debug_hw_1x06.c
+++ b/drivers/gpu/host1x/hw/debug_hw_1x06.c
@@ -87,6 +87,9 @@ static void host1x_debug_show_channel_fifo(struct host1x *host,
 	host1x_debug_output(o, "CMDFIFO_RDATA %08x\n", val);
 
 #if HOST1X_HW <= 6
+	if (!host->hv_regs)
+		return;
+
 	/* Peek pointer values are invalid during SLCG, so disable it */
 	host1x_hypervisor_writel(host, 0x1, HOST1X_HV_ICG_EN_OVERRIDE);
 

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges
  2026-07-02  4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
                   ` (2 preceding siblings ...)
  2026-07-02  4:10 ` [PATCH v2 3/4] gpu: host1x: Support running without hv/common registers Mikko Perttunen
@ 2026-07-02  4:10 ` Mikko Perttunen
  2026-07-02  4:22   ` sashiko-bot
  3 siblings, 1 reply; 6+ messages in thread
From: Mikko Perttunen @ 2026-07-02  4:10 UTC (permalink / raw)
  To: Thierry Reding, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: linux-tegra, dri-devel, devicetree, linux-kernel, Mikko Perttunen

Allow specifying usable channel, and allocatable syncpoint ranges
through the device tree. This is necessary when Host1x resources
are shared between multiple operating systems or independent hardware
units and Linux has limited access to them.

Signed-off-by: Mikko Perttunen <mperttunen@nvidia.com>
---
 drivers/gpu/host1x/channel.c |  6 +++---
 drivers/gpu/host1x/dev.c     | 37 +++++++++++++++++++++++++++++++++++++
 drivers/gpu/host1x/dev.h     |  3 +++
 drivers/gpu/host1x/syncpt.c  | 21 +++++++++++++--------
 4 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
index ca5d0f51cf7d..38fcdda8388a 100644
--- a/drivers/gpu/host1x/channel.c
+++ b/drivers/gpu/host1x/channel.c
@@ -121,13 +121,13 @@ EXPORT_SYMBOL(host1x_channel_put);
 static struct host1x_channel *acquire_unused_channel(struct host1x *host)
 {
 	struct host1x_channel_list *chlist = &host->channel_list;
-	unsigned int max_channels = host->info->nb_channels;
 	unsigned int index;
 
 	mutex_lock(&chlist->lock);
 
-	index = find_first_zero_bit(chlist->allocated_channels, max_channels);
-	if (index >= max_channels) {
+	index = find_next_zero_bit(chlist->allocated_channels,
+				   host->channel_end, host->channel_base);
+	if (index >= host->channel_end) {
 		mutex_unlock(&chlist->lock);
 		dev_err(host->dev, "failed to find free channel\n");
 		return NULL;
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 545fa2e3f180..7103f018cb1b 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -331,6 +331,39 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
 	}
 }
 
+static int host1x_get_assigned_resources(struct host1x *host)
+{
+	struct device_node *np = host->dev->of_node;
+	u32 vals[2];
+	int err;
+
+	err = of_property_read_u32_array(np, "nvidia,channels", vals, 2);
+	if (err == 0) {
+		host->channel_base = vals[0];
+		host->channel_end = vals[0] + vals[1];
+	} else if (err == -EINVAL) {
+		host->channel_base = 0;
+		host->channel_end = host->info->nb_channels;
+	} else {
+		dev_err(host->dev, "invalid nvidia,channels property: %d\n", err);
+		return err;
+	}
+
+	err = of_property_read_u32_array(np, "nvidia,syncpoints", vals, 2);
+	if (err == 0) {
+		host->syncpt_base = vals[0];
+		host->syncpt_end = vals[0] + vals[1];
+	} else if (err == -EINVAL) {
+		host->syncpt_base = 0;
+		host->syncpt_end = host->info->nb_pts;
+	} else {
+		dev_err(host->dev, "invalid nvidia,syncpoints property: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
 static bool host1x_wants_iommu(struct host1x *host1x)
 {
 	/* Our IOMMU usage policy doesn't currently play well with GART */
@@ -602,6 +635,10 @@ static int host1x_probe(struct platform_device *pdev)
 	if (IS_ERR(host->clk))
 		return dev_err_probe(&pdev->dev, PTR_ERR(host->clk), "failed to get clock\n");
 
+	err = host1x_get_assigned_resources(host);
+	if (err)
+		return err;
+
 	err = host1x_get_resets(host);
 	if (err)
 		return err;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index ef44618ed88a..89f1fc838a1c 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -141,6 +141,9 @@ struct host1x {
 	struct reset_control_bulk_data resets[2];
 	unsigned int nresets;
 
+	unsigned int syncpt_base, syncpt_end;
+	unsigned int channel_base, channel_end;
+
 	struct iommu_group *group;
 	struct iommu_domain *domain;
 	struct iova_domain iova;
diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
index 807c74fc6a0a..7760252b3394 100644
--- a/drivers/gpu/host1x/syncpt.c
+++ b/drivers/gpu/host1x/syncpt.c
@@ -59,7 +59,7 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
 					  unsigned long flags,
 					  const char *name)
 {
-	struct host1x_syncpt *sp = host->syncpt;
+	struct host1x_syncpt *sp = host->syncpt + host->syncpt_base;
 	char *full_name;
 	unsigned int i;
 
@@ -68,10 +68,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
 
 	mutex_lock(&host->syncpt_mutex);
 
-	for (i = 0; i < host->info->nb_pts && kref_read(&sp->ref); i++, sp++)
+	for (i = host->syncpt_base; i < host->syncpt_end && kref_read(&sp->ref); i++, sp++)
 		;
 
-	if (i >= host->info->nb_pts)
+	if (i >= host->syncpt_end)
 		goto unlock;
 
 	if (flags & HOST1X_SYNCPT_HAS_BASE) {
@@ -138,7 +138,7 @@ void host1x_syncpt_restore(struct host1x *host)
 	struct host1x_syncpt *sp_base = host->syncpt;
 	unsigned int i;
 
-	for (i = 0; i < host1x_syncpt_nb_pts(host); i++) {
+	for (i = host->syncpt_base; i < host->syncpt_end; i++) {
 		/*
 		 * Unassign syncpt from channels for purposes of Tegra186
 		 * syncpoint protection. This prevents any channel from
@@ -301,6 +301,9 @@ int host1x_syncpt_init(struct host1x *host)
 	for (i = 0; i < host->info->nb_pts; i++) {
 		syncpt[i].id = i;
 		syncpt[i].host = host;
+
+		/* Default to client managed for syncpoints not owned by us */
+		syncpt[i].client_managed = true;
 	}
 
 	for (i = 0; i < host->info->nb_bases; i++)
@@ -310,10 +313,12 @@ int host1x_syncpt_init(struct host1x *host)
 	host->syncpt = syncpt;
 	host->bases = bases;
 
-	/* Allocate sync point to use for clearing waits for expired fences */
-	host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
-	if (!host->nop_sp)
-		return -ENOMEM;
+	/* Prevent syncpoint 0 from being allocated by users */
+	if (host->syncpt_base == 0) {
+		host->nop_sp = host1x_syncpt_alloc(host, 0, "reserved-nop");
+		if (!host->nop_sp)
+			return -ENOMEM;
+	}
 
 	if (host->info->reserve_vblank_syncpts) {
 		kref_init(&host->syncpt[26].ref);

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges
  2026-07-02  4:10 ` [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges Mikko Perttunen
@ 2026-07-02  4:22   ` sashiko-bot
  0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-07-02  4:22 UTC (permalink / raw)
  To: Mikko Perttunen; +Cc: devicetree, conor+dt, robh, dri-devel

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Unvalidated device tree properties `nvidia,channels` and `nvidia,syncpoints` lead to out-of-bounds array accesses.
--

commit c583bec6dab6b936ed8b99cb1df24a3d2f9ac317
Author: Mikko Perttunen <mperttunen@nvidia.com>

gpu: host1x: Allow limiting usable channel and syncpoint ranges

This commit allows specifying usable channel and allocatable syncpoint
ranges through the device tree. This is necessary when Host1x resources
are shared between multiple operating systems or independent hardware units.

> diff --git a/drivers/gpu/host1x/channel.c b/drivers/gpu/host1x/channel.c
> index ca5d0f51cf7da..38fcdda8388ad 100644
> --- a/drivers/gpu/host1x/channel.c
> +++ b/drivers/gpu/host1x/channel.c
> @@ -121,13 +121,13 @@ EXPORT_SYMBOL(host1x_channel_put);
>  static struct host1x_channel *acquire_unused_channel(struct host1x *host)
>  {
>  	struct host1x_channel_list *chlist = &host->channel_list;
> -	unsigned int max_channels = host->info->nb_channels;
>  	unsigned int index;
>  
>  	mutex_lock(&chlist->lock);
>  
> -	index = find_first_zero_bit(chlist->allocated_channels, max_channels);
> -	if (index >= max_channels) {
> +	index = find_next_zero_bit(chlist->allocated_channels,
> +				   host->channel_end, host->channel_base);
> +	if (index >= host->channel_end) {

[Severity: High]
Could this result in an out-of-bounds access if the device tree specifies a
range larger than host->info->nb_channels?

The bitmap chlist->allocated_channels is sized according to the hardware
maximum, but host->channel_end is parsed directly from the device tree
without bounds checking.

[ ... ]

> diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
> index 545fa2e3f180c..7103f018cb1bf 100644
> --- a/drivers/gpu/host1x/dev.c
> +++ b/drivers/gpu/host1x/dev.c
> @@ -331,6 +331,39 @@ static void host1x_setup_virtualization_tables(struct host1x *host)
>  	}
>  }
>  
> +static int host1x_get_assigned_resources(struct host1x *host)
> +{
> +	struct device_node *np = host->dev->of_node;
> +	u32 vals[2];
> +	int err;
> +
> +	err = of_property_read_u32_array(np, "nvidia,channels", vals, 2);
> +	if (err == 0) {
> +		host->channel_base = vals[0];
> +		host->channel_end = vals[0] + vals[1];

[Severity: High]
Should we validate these parsed bounds against host->info->nb_channels?

Without a check, a malformed or dynamically loaded device tree with
excessively large ranges can cause out-of-bounds accesses during allocation.

> +	} else if (err == -EINVAL) {
> +		host->channel_base = 0;
> +		host->channel_end = host->info->nb_channels;
> +	} else {
> +		dev_err(host->dev, "invalid nvidia,channels property: %d\n", err);
> +		return err;
> +	}
> +
> +	err = of_property_read_u32_array(np, "nvidia,syncpoints", vals, 2);
> +	if (err == 0) {
> +		host->syncpt_base = vals[0];
> +		host->syncpt_end = vals[0] + vals[1];

[Severity: High]
Similarly, should we check host->syncpt_end against host->info->nb_pts
here to prevent out-of-bounds pointer dereferences later in
host1x_syncpt_alloc()?

[ ... ]

> diff --git a/drivers/gpu/host1x/syncpt.c b/drivers/gpu/host1x/syncpt.c
> index 807c74fc6a0ac..7760252b3394e 100644
> --- a/drivers/gpu/host1x/syncpt.c
> +++ b/drivers/gpu/host1x/syncpt.c
> @@ -59,7 +59,7 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
>  					  unsigned long flags,
>  					  const char *name)
>  {
> -	struct host1x_syncpt *sp = host->syncpt;
> +	struct host1x_syncpt *sp = host->syncpt + host->syncpt_base;
>  	char *full_name;
>  	unsigned int i;
>  
> @@ -68,10 +68,10 @@ struct host1x_syncpt *host1x_syncpt_alloc(struct host1x *host,
>  
>  	mutex_lock(&host->syncpt_mutex);
>  
> -	for (i = 0; i < host->info->nb_pts && kref_read(&sp->ref); i++, sp++)
> +	for (i = host->syncpt_base; i < host->syncpt_end && kref_read(&sp->ref); i++, sp++)

[Severity: High]
Can this loop dereference sp->ref out of bounds if the device tree specifies
a syncpt_end larger than the size of the host->syncpt array?

The underlying array is allocated based on host->info->nb_pts.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260702-host1x-nohv-v2-0-e6d88bac0af6@nvidia.com?part=4

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-07-02  4:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-02  4:10 [PATCH v2 0/4] Support partitioned Host1x Mikko Perttunen
2026-07-02  4:10 ` [PATCH v2 1/4] dt-bindings: display: tegra: Make non-vm registers optional Mikko Perttunen
2026-07-02  4:10 ` [PATCH v2 2/4] dt-bindings: display: tegra: Add channel/syncpoint range properties Mikko Perttunen
2026-07-02  4:10 ` [PATCH v2 3/4] gpu: host1x: Support running without hv/common registers Mikko Perttunen
2026-07-02  4:10 ` [PATCH v2 4/4] gpu: host1x: Allow limiting usable channel and syncpoint ranges Mikko Perttunen
2026-07-02  4:22   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox