* [PATCH 1/6] nouveau/gsp: refactor libos entry handling for r535.
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
2026-07-29 4:15 ` [PATCH 2/6] nouveau/gsp: make libos init per-gsp version Dave Airlie
` (4 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
This just refactors the libos entries that are the same pattern,
allocate + fill out entry.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 49 ++++++++++---------
1 file changed, 25 insertions(+), 24 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index f544afa12b6b..f4f4142ec8d0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -1470,6 +1470,28 @@ static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size)
ptes[i] = (u64)addr + (i << GSP_PAGE_SHIFT);
}
+static int
+gsp_fill_libos_entry(struct nvkm_gsp *gsp,
+ LibosMemoryRegionInitArgument *arg,
+ size_t size,
+ struct nvkm_gsp_mem *mem,
+ const char *name)
+{
+ int ret;
+
+ ret = nvkm_gsp_mem_ctor(gsp, size, mem);
+ if (ret)
+ return ret;
+
+ arg->id8 = r535_gsp_libos_id8(name);
+ arg->pa = mem->addr;
+ arg->size = mem->size;
+ arg->kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
+ arg->loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
+ create_pte_array(mem->data + sizeof(u64), mem->addr, mem->size);
+ return 0;
+}
+
/**
* r535_gsp_libos_init() -- create the libos arguments structure
* @gsp: gsp pointer
@@ -1516,39 +1538,18 @@ r535_gsp_libos_init(struct nvkm_gsp *gsp)
args = gsp->libos.data;
- ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->loginit);
+ ret = gsp_fill_libos_entry(gsp, &args[0], 0x10000, &gsp->loginit, "LOGINIT");
if (ret)
return ret;
- args[0].id8 = r535_gsp_libos_id8("LOGINIT");
- args[0].pa = gsp->loginit.addr;
- args[0].size = gsp->loginit.size;
- args[0].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
- args[0].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
- create_pte_array(gsp->loginit.data + sizeof(u64), gsp->loginit.addr, gsp->loginit.size);
-
- ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->logintr);
+ ret = gsp_fill_libos_entry(gsp, &args[1], 0x10000, &gsp->logintr, "LOGINTR");
if (ret)
return ret;
- args[1].id8 = r535_gsp_libos_id8("LOGINTR");
- args[1].pa = gsp->logintr.addr;
- args[1].size = gsp->logintr.size;
- args[1].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
- args[1].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
- create_pte_array(gsp->logintr.data + sizeof(u64), gsp->logintr.addr, gsp->logintr.size);
-
- ret = nvkm_gsp_mem_ctor(gsp, 0x10000, &gsp->logrm);
+ ret = gsp_fill_libos_entry(gsp, &args[2], 0x10000, &gsp->logrm, "LOGRM");
if (ret)
return ret;
- args[2].id8 = r535_gsp_libos_id8("LOGRM");
- args[2].pa = gsp->logrm.addr;
- args[2].size = gsp->logrm.size;
- args[2].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
- args[2].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
- create_pte_array(gsp->logrm.data + sizeof(u64), gsp->logrm.addr, gsp->logrm.size);
-
ret = r535_gsp_rmargs_init(gsp, false);
if (ret)
return ret;
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/6] nouveau/gsp: make libos init per-gsp version.
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
2026-07-29 4:15 ` [PATCH 1/6] nouveau/gsp: refactor libos entry handling for r535 Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
2026-07-29 4:32 ` sashiko-bot
2026-07-29 4:15 ` [PATCH 3/6] nouveau/gsp: add logging entries for r570 Dave Airlie
` (3 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
This makes it a per-gsp thing, but just adds r570 as a copy of r535
for now.
r570 will be enhanced next.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 23 ++-----
.../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 68 +++++++++++++++++++
.../nvkm/subdev/gsp/rm/r570/nvrm/gsp.h | 23 +++++++
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 16 +++++
4 files changed, 114 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index f4f4142ec8d0..8e1ad2e79d3e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -1205,7 +1205,7 @@ r535_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume)
}
}
-static int
+int
r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume)
{
int ret;
@@ -1362,7 +1362,7 @@ static struct dentry *create_debugfs(struct nvkm_gsp *gsp, const char *name,
* r535_gsp_booter_load() is called, so that if GSP-RM fails to initialize,
* there could still be a log to capture.
*/
-static void
+void
r535_gsp_libos_debugfs_init(struct nvkm_gsp *gsp)
{
struct device *dev = gsp->subdev.device->dev;
@@ -1433,17 +1433,6 @@ r535_gsp_libos_debugfs_init(struct nvkm_gsp *gsp)
#endif
-static inline u64
-r535_gsp_libos_id8(const char *name)
-{
- u64 id = 0;
-
- for (int i = 0; i < sizeof(id) && *name; i++, name++)
- id = (id << 8) | *name;
-
- return id;
-}
-
/**
* create_pte_array() - creates a PTE array of a physically contiguous buffer
* @ptes: pointer to the array
@@ -1461,7 +1450,8 @@ r535_gsp_libos_id8(const char *name)
*
* See memdescGetPhysAddrsForGpu()
*/
-static void create_pte_array(u64 *ptes, dma_addr_t addr, size_t size)
+void
+r535_gsp_create_pte_array(u64 *ptes, dma_addr_t addr, size_t size)
{
unsigned int num_pages = DIV_ROUND_UP_ULL(size, GSP_PAGE_SIZE);
unsigned int i;
@@ -1488,7 +1478,7 @@ gsp_fill_libos_entry(struct nvkm_gsp *gsp,
arg->size = mem->size;
arg->kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
arg->loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
- create_pte_array(mem->data + sizeof(u64), mem->addr, mem->size);
+ r535_gsp_create_pte_array(mem->data + sizeof(u64), mem->addr, mem->size);
return 0;
}
@@ -2187,7 +2177,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp)
/* Release FW images - we've copied them to DMA buffers now. */
nvkm_gsp_dtor_fws(gsp);
- ret = r535_gsp_libos_init(gsp);
+ ret = rmapi->gsp->libos_init(gsp);
if (WARN_ON(ret))
return ret;
@@ -2206,6 +2196,7 @@ r535_gsp_oneinit(struct nvkm_gsp *gsp)
const struct nvkm_rm_api_gsp
r535_gsp = {
+ .libos_init = r535_gsp_libos_init,
.set_rmargs = r535_gsp_set_rmargs,
.set_system_info = r535_gsp_set_system_info,
.get_static_info = r535_gsp_get_static_info,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
index 996941c668ba..64011430f4c0 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
@@ -205,8 +205,76 @@ r570_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume)
args->bDmemStack = 1;
}
+static int
+gsp_fill_libos_entry(struct nvkm_gsp *gsp,
+ LibosMemoryRegionInitArgument *arg,
+ size_t size,
+ struct nvkm_gsp_mem *mem,
+ const char *name)
+{
+ int ret;
+
+ ret = nvkm_gsp_mem_ctor(gsp, size, mem);
+ if (ret)
+ return ret;
+
+ arg->id8 = r535_gsp_libos_id8(name);
+ arg->pa = mem->addr;
+ arg->size = mem->size;
+ arg->kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
+ arg->loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
+ r535_gsp_create_pte_array(mem->data + sizeof(u64), mem->addr, mem->size);
+ return 0;
+}
+
+/**
+ * r570_gsp_libos_init() -- create the libos arguments structure
+ * @gsp: gsp pointer
+ */
+static int
+r570_gsp_libos_init(struct nvkm_gsp *gsp)
+{
+ LibosMemoryRegionInitArgument *args;
+ int ret;
+
+ ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->libos);
+ if (ret)
+ return ret;
+
+ args = gsp->libos.data;
+
+ ret = gsp_fill_libos_entry(gsp, &args[0], 0x10000, &gsp->loginit, "LOGINIT");
+ if (ret)
+ return ret;
+
+ ret = gsp_fill_libos_entry(gsp, &args[1], 0x10000, &gsp->logintr, "LOGINTR");
+ if (ret)
+ return ret;
+
+ ret = gsp_fill_libos_entry(gsp, &args[2], 0x10000, &gsp->logrm, "LOGRM");
+ if (ret)
+ return ret;
+
+ ret = r535_gsp_rmargs_init(gsp, false);
+ if (ret)
+ return ret;
+
+ args[3].id8 = r535_gsp_libos_id8("RMARGS");
+ args[3].pa = gsp->rmargs.addr;
+ args[3].size = gsp->rmargs.size;
+ args[3].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
+ args[3].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
+
+#ifdef CONFIG_DEBUG_FS
+ r535_gsp_libos_debugfs_init(gsp);
+#endif
+
+ return 0;
+}
+
const struct nvkm_rm_api_gsp
r570_gsp = {
+ .libos_init = r570_gsp_libos_init,
.set_rmargs = r570_gsp_set_rmargs,
.set_system_info = r570_gsp_set_system_info,
.get_static_info = r570_gsp_get_static_info,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
index b6075021e74f..23c30cbdefff 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
@@ -523,6 +523,29 @@ typedef struct
#define NV2080_CTRL_GPU_SET_POWER_STATE_GPU_LEVEL_3 (0x00000003U)
+typedef NvU64 LibosAddress;
+
+typedef struct
+{
+ LibosAddress id8; // Id tag.
+ LibosAddress pa; // Physical address.
+ LibosAddress size; // Size of memory area.
+ NvU8 kind; // See LibosMemoryRegionKind above.
+ NvU8 loc; // See LibosMemoryRegionLoc above.
+} LibosMemoryRegionInitArgument;
+
+typedef enum {
+ LIBOS_MEMORY_REGION_NONE,
+ LIBOS_MEMORY_REGION_CONTIGUOUS,
+ LIBOS_MEMORY_REGION_RADIX3
+} LibosMemoryRegionKind;
+
+typedef enum {
+ LIBOS_MEMORY_REGION_LOC_NONE,
+ LIBOS_MEMORY_REGION_LOC_SYSMEM,
+ LIBOS_MEMORY_REGION_LOC_FB
+} LibosMemoryRegionLoc;
+
typedef struct
{
// Magic for verification by secure ucode
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
index a9af94adf9ef..cc9f33202673 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
@@ -32,6 +32,7 @@ struct nvkm_rm_wpr {
struct nvkm_rm_api {
const struct nvkm_rm_api_gsp {
+ int (*libos_init)(struct nvkm_gsp *);
void (*set_rmargs)(struct nvkm_gsp *, bool resume);
int (*set_system_info)(struct nvkm_gsp *);
int (*get_static_info)(struct nvkm_gsp *);
@@ -144,6 +145,9 @@ void r535_gsp_acpi_caps(acpi_handle, CAPS_METHOD_DATA *);
struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS;
void r535_gsp_get_static_info_fb(struct nvkm_gsp *,
const struct NV2080_CTRL_CMD_FB_GET_FB_REGION_INFO_PARAMS *);
+void r535_gsp_create_pte_array(u64 *ptes, dma_addr_t addr, size_t size);
+int r535_gsp_rmargs_init(struct nvkm_gsp *gsp, bool resume);
+void r535_gsp_libos_debugfs_init(struct nvkm_gsp *gsp);
extern const struct nvkm_rm_api_rpc r535_rpc;
extern const struct nvkm_rm_api_ctrl r535_ctrl;
extern const struct nvkm_rm_api_alloc r535_alloc;
@@ -188,4 +192,16 @@ extern const struct nvkm_rm_api_gr r570_gr;
int r570_gr_gpc_mask(struct nvkm_gsp *, u32 *mask);
int r570_gr_tpc_mask(struct nvkm_gsp *, int gpc, u32 *mask);
extern const struct nvkm_rm_api_engine r570_ofa;
+
+static inline u64
+r535_gsp_libos_id8(const char *name)
+{
+ u64 id = 0;
+
+ for (int i = 0; i < sizeof(id) && *name; i++, name++)
+ id = (id << 8) | *name;
+
+ return id;
+}
+
#endif
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 2/6] nouveau/gsp: make libos init per-gsp version.
2026-07-29 4:15 ` [PATCH 2/6] nouveau/gsp: make libos init per-gsp version Dave Airlie
@ 2026-07-29 4:32 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-29 4:32 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [Medium] DMA buffers for GSP logging (`gsp->libos`) and boot firmware (`gsp->boot.fw`) are leaked on the initialization error path.
--
--- Patch [2]: [PATCH 2/6] nouveau/gsp: make libos init per-gsp version. ---
commit 85ebb9d2d6335df98fac564dbbe77909c7d38c2b
Author: Dave Airlie <airlied@redhat.com>
nouveau/gsp: make libos init per-gsp version.
This makes libos initialization a per-gsp version feature. It adds r570 as a
copy of r535 for now, with enhancements to r570 expected next.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> index 996941c668ba9..64011430f4c0a 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
[ ... ]
> @@ -205,8 +205,76 @@ r570_gsp_set_rmargs(struct nvkm_gsp *gsp, bool resume)
[ ... ]
> +/**
> + * r570_gsp_libos_init() -- create the libos arguments structure
> + * @gsp: gsp pointer
> + */
> +static int
> +r570_gsp_libos_init(struct nvkm_gsp *gsp)
> +{
> + LibosMemoryRegionInitArgument *args;
> + int ret;
> +
> + ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->libos);
[Severity: Medium]
This is a pre-existing issue, but does this leak the gsp->libos and
gsp->boot.fw DMA buffers on the initialization error path?
If GSP initialization fails after libos_init is called but before postinit
executes (for example, if set_system_info or RPC registry configuration
fails), the initialization falls back to tearing down the subdevice via
r535_gsp_dtor().
While postinit frees these buffers on a successful boot, r535_gsp_dtor()
appears to skip freeing gsp->libos and gsp->boot.fw when cleaning up on
the error path.
> + if (ret)
> + return ret;
> +
> + args = gsp->libos.data;
> +
> + ret = gsp_fill_libos_entry(gsp, &args[0], 0x10000, &gsp->loginit, "LOGINIT");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260729041653.3985549-1-airlied@gmail.com?part=2
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/6] nouveau/gsp: add logging entries for r570
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
2026-07-29 4:15 ` [PATCH 1/6] nouveau/gsp: refactor libos entry handling for r535 Dave Airlie
2026-07-29 4:15 ` [PATCH 2/6] nouveau/gsp: make libos init per-gsp version Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
2026-07-29 4:33 ` sashiko-bot
2026-07-29 4:15 ` [PATCH 4/6] nouveau/gsp: refactor the chan allocation arguments into a struct Dave Airlie
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
r570 adds logmnoc and logkrnl. logkrnl is only used for libos3, so
add a flag to pick libos2 out and not init on that.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
.../gpu/drm/nouveau/include/nvkm/subdev/gsp.h | 2 ++
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 2 ++
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c | 1 +
.../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 23 +++++++++++++++----
.../drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c | 1 +
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 1 +
6 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
index 64fed208e4cf..d45351ce08a1 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h
@@ -145,6 +145,8 @@ struct nvkm_gsp {
struct nvkm_gsp_mem loginit;
struct nvkm_gsp_mem logintr;
struct nvkm_gsp_mem logrm;
+ struct nvkm_gsp_mem logmnoc;
+ struct nvkm_gsp_mem logkrnl;
struct nvkm_gsp_mem rmargs;
struct nvkm_gsp_mem wpr_meta;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index 8e1ad2e79d3e..77a5a1882472 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -2108,6 +2108,8 @@ r535_gsp_dtor(struct nvkm_gsp *gsp)
r535_gsp_libos_debugfs_fini(gsp);
+ nvkm_gsp_mem_dtor(&gsp->logkrnl);
+ nvkm_gsp_mem_dtor(&gsp->logmnoc);
nvkm_gsp_mem_dtor(&gsp->loginit);
nvkm_gsp_mem_dtor(&gsp->logintr);
nvkm_gsp_mem_dtor(&gsp->logrm);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c
index a4190676e1ad..e198212df9c5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/rm.c
@@ -11,6 +11,7 @@ r535_wpr_libos2 = {
.os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2,
.base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X,
.heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB,
+ .is_libos2 = true,
};
static const struct nvkm_rm_wpr
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
index 64011430f4c0..d9786830153d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
@@ -236,6 +236,7 @@ r570_gsp_libos_init(struct nvkm_gsp *gsp)
{
LibosMemoryRegionInitArgument *args;
int ret;
+ int idx;
ret = nvkm_gsp_mem_ctor(gsp, 0x1000, &gsp->libos);
if (ret)
@@ -255,15 +256,27 @@ r570_gsp_libos_init(struct nvkm_gsp *gsp)
if (ret)
return ret;
+ ret = gsp_fill_libos_entry(gsp, &args[3], 0x10000, &gsp->logmnoc, "LOGMNOC");
+ if (ret)
+ return ret;
+
+ idx = 4;
+ if (!gsp->rm->wpr->is_libos2) {
+ ret = gsp_fill_libos_entry(gsp, &args[idx], 0x10000, &gsp->logkrnl, "LOGKRNL");
+ if (ret)
+ return ret;
+ idx++;
+ }
+
ret = r535_gsp_rmargs_init(gsp, false);
if (ret)
return ret;
- args[3].id8 = r535_gsp_libos_id8("RMARGS");
- args[3].pa = gsp->rmargs.addr;
- args[3].size = gsp->rmargs.size;
- args[3].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
- args[3].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
+ args[idx].id8 = r535_gsp_libos_id8("RMARGS");
+ args[idx].pa = gsp->rmargs.addr;
+ args[idx].size = gsp->rmargs.size;
+ args[idx].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
+ args[idx].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
#ifdef CONFIG_DEBUG_FS
r535_gsp_libos_debugfs_init(gsp);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c
index 498658d0c60c..fa012756a731 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/rm.c
@@ -11,6 +11,7 @@ r570_wpr_libos2 = {
.os_carveout_size = GSP_FW_HEAP_PARAM_OS_SIZE_LIBOS2,
.base_size = GSP_FW_HEAP_PARAM_BASE_RM_SIZE_TU10X,
.heap_size_min = GSP_FW_HEAP_SIZE_OVERRIDE_LIBOS2_MIN_MB,
+ .is_libos2 = true,
};
static const struct nvkm_rm_wpr
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
index cc9f33202673..b77059e0ac12 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
@@ -28,6 +28,7 @@ struct nvkm_rm_wpr {
u32 heap_size_non_wpr;
u32 rsvd_size_pmu;
bool offset_set_by_acr;
+ bool is_libos2;
};
struct nvkm_rm_api {
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 3/6] nouveau/gsp: add logging entries for r570
2026-07-29 4:15 ` [PATCH 3/6] nouveau/gsp: add logging entries for r570 Dave Airlie
@ 2026-07-29 4:33 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-29 4:33 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Newly added `logmnoc` and `logkrnl` logging buffers are allocated and passed to GSP-RM, but they are not exported to debugfs or retained on failure, making them entirely inaccessible to userspace.
--
--- Patch [3]: [PATCH 3/6] nouveau/gsp: add logging entries for r570 ---
commit bbe0f1142019c1da5450d6ce1f59020ffc413ec2
Author: Dave Airlie <airlied@redhat.com>
nouveau/gsp: add logging entries for r570
r570 adds logmnoc and logkrnl. logkrnl is only used for libos3, so
add a flag to pick libos2 out and not init on that.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> index 64011430f4c0a..d9786830153da 100644
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
[ ... ]
> @@ -255,15 +256,27 @@ r570_gsp_libos_init(struct nvkm_gsp *gsp)
> if (ret)
> return ret;
>
> + ret = gsp_fill_libos_entry(gsp, &args[3], 0x10000, &gsp->logmnoc, "LOGMNOC");
> + if (ret)
> + return ret;
> +
> + idx = 4;
> + if (!gsp->rm->wpr->is_libos2) {
> + ret = gsp_fill_libos_entry(gsp, &args[idx], 0x10000, &gsp->logkrnl, "LOGKRNL");
> + if (ret)
> + return ret;
> + idx++;
> + }
> +
> ret = r535_gsp_rmargs_init(gsp, false);
> if (ret)
> return ret;
>
> - args[3].id8 = r535_gsp_libos_id8("RMARGS");
> - args[3].pa = gsp->rmargs.addr;
> - args[3].size = gsp->rmargs.size;
> - args[3].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
> - args[3].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
> + args[idx].id8 = r535_gsp_libos_id8("RMARGS");
> + args[idx].pa = gsp->rmargs.addr;
> + args[idx].size = gsp->rmargs.size;
> + args[idx].kind = LIBOS_MEMORY_REGION_CONTIGUOUS;
> + args[idx].loc = LIBOS_MEMORY_REGION_LOC_SYSMEM;
>
> #ifdef CONFIG_DEBUG_FS
> r535_gsp_libos_debugfs_init(gsp);
[Severity: Medium]
Are these new logging buffers missing debugfs integration?
Looking at r535_gsp_libos_debugfs_init(), it doesn't appear to be updated
to expose the newly allocated logmnoc and logkrnl buffers to userspace.
Additionally, will these logs be retained on initialization failure if
r535_gsp_retain_logging() is also not updated to handle them?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260729041653.3985549-1-airlied@gmail.com?part=3
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/6] nouveau/gsp: refactor the chan allocation arguments into a struct
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
` (2 preceding siblings ...)
2026-07-29 4:15 ` [PATCH 3/6] nouveau/gsp: add logging entries for r570 Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
2026-07-29 4:15 ` [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info Dave Airlie
2026-07-29 4:15 ` [PATCH 6/6] nouveau: set wpr boost flags like open driver does Dave Airlie
5 siblings, 0 replies; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
this has a lot of args, and it wants to grow more in the future,
lets just refactor this out and make it cleaner.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
.../nouveau/nvkm/subdev/gsp/rm/r535/fifo.c | 48 +++++++++++--------
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c | 18 +++++--
.../nouveau/nvkm/subdev/gsp/rm/r570/fifo.c | 31 ++++++------
.../drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c | 18 +++++--
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 17 +++++--
5 files changed, 83 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
index 76ee938efea3..6603b1951772 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fifo.c
@@ -72,15 +72,14 @@ r535_chan_ramfc_clear(struct nvkm_chan *chan)
#define CHID_PER_USERD 8
static int
-r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_type, u8 runq,
- bool priv, int chid, u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr,
- struct nvkm_vmm *vmm, u64 gpfifo_offset, u32 gpfifo_length,
+r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle,
+ const struct nvkm_rm_chan_alloc_args *chan_args,
struct nvkm_gsp_object *chan)
{
struct nvkm_gsp *gsp = device->object.client->gsp;
struct nvkm_fifo *fifo = gsp->subdev.device->fifo;
- const int userd_p = chid / CHID_PER_USERD;
- const int userd_i = chid % CHID_PER_USERD;
+ const int userd_p = chan_args->chid / CHID_PER_USERD;
+ const int userd_i = chan_args->chid % CHID_PER_USERD;
NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args;
args = nvkm_gsp_rm_alloc_get(&device->object, handle,
@@ -88,14 +87,14 @@ r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_ty
if (WARN_ON(IS_ERR(args)))
return PTR_ERR(args);
- args->gpFifoOffset = gpfifo_offset;
- args->gpFifoEntries = gpfifo_length / 8;
+ args->gpFifoOffset = chan_args->gpfifo_offset;
+ args->gpFifoEntries = chan_args->gpfifo_length / 8;
args->flags = NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL);
args->flags |= NVDEF(NVOS04, FLAGS, VPR, FALSE);
args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE);
- args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, runq);
- if (!priv)
+ args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, chan_args->runq);
+ if (!chan_args->priv)
args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, FALSE);
else
args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, TRUE);
@@ -117,30 +116,30 @@ r535_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_ty
args->flags |= NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE);
args->flags |= NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE);
- args->hVASpace = vmm->rm.object.handle;
- args->engineType = nv2080_engine_type;
+ args->hVASpace = chan_args->vmm->rm.object.handle;
+ args->engineType = chan_args->nv2080_engine_type;
- args->instanceMem.base = inst_addr;
+ args->instanceMem.base = chan_args->inst_addr;
args->instanceMem.size = fifo->func->chan.func->inst->size;
args->instanceMem.addressSpace = 2;
args->instanceMem.cacheAttrib = 1;
- args->userdMem.base = userd_addr;
+ args->userdMem.base = chan_args->userd_addr;
args->userdMem.size = fifo->func->chan.func->userd->size;
args->userdMem.addressSpace = 2;
args->userdMem.cacheAttrib = 1;
- args->ramfcMem.base = inst_addr;
+ args->ramfcMem.base = chan_args->inst_addr;
args->ramfcMem.size = 0x200;
args->ramfcMem.addressSpace = 2;
args->ramfcMem.cacheAttrib = 1;
- args->mthdbufMem.base = mthdbuf_addr;
+ args->mthdbufMem.base = chan_args->mthdbuf_addr;
args->mthdbufMem.size = fifo->rm.mthdbuf_size;
args->mthdbufMem.addressSpace = 1;
args->mthdbufMem.cacheAttrib = 0;
- if (!priv)
+ if (!chan_args->priv)
args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, USER);
else
args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, ADMIN);
@@ -180,11 +179,20 @@ r535_chan_ramfc_write(struct nvkm_chan *chan, u64 offset, u64 length, u32 devm,
if (!chan->rm.mthdbuf.ptr)
return -ENOMEM;
+ struct nvkm_rm_chan_alloc_args chan_args = {
+ .nv2080_engine_type = eT,
+ .runq = chan->runq,
+ .priv = priv,
+ .chid = chan->id,
+ .inst_addr = chan->inst->addr,
+ .userd_addr = nvkm_memory_addr(chan->userd.mem) + chan->userd.base,
+ .mthdbuf_addr = chan->rm.mthdbuf.addr,
+ .vmm = chan->vmm,
+ .gpfifo_offset = offset,
+ .gpfifo_length = length
+ };
ret = rmapi->fifo->chan.alloc(&chan->vmm->rm.device, NVKM_RM_CHAN(chan->id),
- eT, chan->runq, priv, chan->id, chan->inst->addr,
- nvkm_memory_addr(chan->userd.mem) + chan->userd.base,
- chan->rm.mthdbuf.addr, chan->vmm, offset, length,
- &chan->rm.object);
+ &chan_args, &chan->rm.object);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
index 034db286d285..4bec793a2caf 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gr.c
@@ -301,12 +301,20 @@ r535_gr_oneinit(struct nvkm_gr *base)
if (ret)
goto done;
+ struct nvkm_rm_chan_alloc_args chan_args = {
+ .nv2080_engine_type = 1,
+ .runq = 0,
+ .priv = true,
+ .chid = rm->api->fifo->rsvd_chids,
+ .inst_addr = nvkm_memory_addr(golden.inst),
+ .userd_addr = nvkm_memory_addr(golden.inst) + 0x1000,
+ .mthdbuf_addr = nvkm_memory_addr(golden.inst) + 0x2000,
+ .vmm = golden.vmm,
+ .gpfifo_offset = 0,
+ .gpfifo_length = 0x1000
+ };
ret = rm->api->fifo->chan.alloc(&golden.vmm->rm.device, NVKM_RM_CHAN(0),
- 1, 0, true, rm->api->fifo->rsvd_chids,
- nvkm_memory_addr(golden.inst),
- nvkm_memory_addr(golden.inst) + 0x1000,
- nvkm_memory_addr(golden.inst) + 0x2000,
- golden.vmm, 0, 0x1000, &golden.chan);
+ &chan_args, &golden.chan);
if (ret)
goto done;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c
index 79132805cfcf..e28c7251ea10 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/fifo.c
@@ -17,15 +17,14 @@
#define CHID_PER_USERD 8
static int
-r570_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_type, u8 runq,
- bool priv, int chid, u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr,
- struct nvkm_vmm *vmm, u64 gpfifo_offset, u32 gpfifo_length,
+r570_chan_alloc(struct nvkm_gsp_device *device, u32 handle,
+ const struct nvkm_rm_chan_alloc_args *chan_args,
struct nvkm_gsp_object *chan)
{
struct nvkm_gsp *gsp = device->object.client->gsp;
struct nvkm_fifo *fifo = gsp->subdev.device->fifo;
- const int userd_p = chid / CHID_PER_USERD;
- const int userd_i = chid % CHID_PER_USERD;
+ const int userd_p = chan_args->chid / CHID_PER_USERD;
+ const int userd_i = chan_args->chid % CHID_PER_USERD;
NV_CHANNELGPFIFO_ALLOCATION_PARAMETERS *args;
args = nvkm_gsp_rm_alloc_get(&device->object, handle,
@@ -33,14 +32,14 @@ r570_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_ty
if (WARN_ON(IS_ERR(args)))
return PTR_ERR(args);
- args->gpFifoOffset = gpfifo_offset;
- args->gpFifoEntries = gpfifo_length / 8;
+ args->gpFifoOffset = chan_args->gpfifo_offset;
+ args->gpFifoEntries = chan_args->gpfifo_length / 8;
args->flags = NVDEF(NVOS04, FLAGS, CHANNEL_TYPE, PHYSICAL);
args->flags |= NVDEF(NVOS04, FLAGS, VPR, FALSE);
args->flags |= NVDEF(NVOS04, FLAGS, CHANNEL_SKIP_MAP_REFCOUNTING, FALSE);
- args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, runq);
- if (!priv)
+ args->flags |= NVVAL(NVOS04, FLAGS, GROUP_CHANNEL_RUNQUEUE, chan_args->runq);
+ if (!chan_args->priv)
args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, FALSE);
else
args->flags |= NVDEF(NVOS04, FLAGS, PRIVILEGED_CHANNEL, TRUE);
@@ -62,30 +61,30 @@ r570_chan_alloc(struct nvkm_gsp_device *device, u32 handle, u32 nv2080_engine_ty
args->flags |= NVDEF(NVOS04, FLAGS, MAP_CHANNEL, FALSE);
args->flags |= NVDEF(NVOS04, FLAGS, SKIP_CTXBUFFER_ALLOC, FALSE);
- args->hVASpace = vmm->rm.object.handle;
- args->engineType = nv2080_engine_type;
+ args->hVASpace = chan_args->vmm->rm.object.handle;
+ args->engineType = chan_args->nv2080_engine_type;
- args->instanceMem.base = inst_addr;
+ args->instanceMem.base = chan_args->inst_addr;
args->instanceMem.size = fifo->func->chan.func->inst->size;
args->instanceMem.addressSpace = 2;
args->instanceMem.cacheAttrib = 1;
- args->userdMem.base = userd_addr;
+ args->userdMem.base = chan_args->userd_addr;
args->userdMem.size = fifo->func->chan.func->userd->size;
args->userdMem.addressSpace = 2;
args->userdMem.cacheAttrib = 1;
- args->ramfcMem.base = inst_addr;
+ args->ramfcMem.base = chan_args->inst_addr;
args->ramfcMem.size = 0x200;
args->ramfcMem.addressSpace = 2;
args->ramfcMem.cacheAttrib = 1;
- args->mthdbufMem.base = mthdbuf_addr;
+ args->mthdbufMem.base = chan_args->mthdbuf_addr;
args->mthdbufMem.size = fifo->rm.mthdbuf_size;
args->mthdbufMem.addressSpace = 1;
args->mthdbufMem.cacheAttrib = 0;
- if (!priv)
+ if (!chan_args->priv)
args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, USER);
else
args->internalFlags = NVDEF(NV_KERNELCHANNEL, ALLOC_INTERNALFLAGS, PRIVILEGE, ADMIN);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c
index 8dd4552aeaa5..354562ba9d35 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gr.c
@@ -130,12 +130,20 @@ r570_gr_scrubber_init(struct r535_gr *gr)
if (ret)
goto done;
+ struct nvkm_rm_chan_alloc_args chan_args = {
+ .nv2080_engine_type = NV2080_ENGINE_TYPE_GR0,
+ .runq = 0,
+ .priv = false,
+ .chid = gr->scrubber.chid,
+ .inst_addr = nvkm_memory_addr(gr->scrubber.inst),
+ .userd_addr = nvkm_memory_addr(gr->scrubber.inst) + 0x1000,
+ .mthdbuf_addr = nvkm_memory_addr(gr->scrubber.inst) + 0x2000,
+ .vmm = gr->scrubber.vmm,
+ .gpfifo_offset = 0,
+ .gpfifo_length = 0x1000,
+ };
ret = rm->api->fifo->chan.alloc(&gr->scrubber.vmm->rm.device, KGRAPHICS_SCRUBBER_HANDLE_CHANNEL,
- NV2080_ENGINE_TYPE_GR0, 0, false, gr->scrubber.chid,
- nvkm_memory_addr(gr->scrubber.inst),
- nvkm_memory_addr(gr->scrubber.inst) + 0x1000,
- nvkm_memory_addr(gr->scrubber.inst) + 0x2000,
- gr->scrubber.vmm, 0, 0x1000, &gr->scrubber.chan);
+ &chan_args, &gr->scrubber.chan);
if (ret)
goto done;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
index b77059e0ac12..b71ba74eec12 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
@@ -31,6 +31,19 @@ struct nvkm_rm_wpr {
bool is_libos2;
};
+struct nvkm_rm_chan_alloc_args {
+ u32 nv2080_engine_type;
+ u8 runq;
+ bool priv;
+ int chid;
+ u64 inst_addr;
+ u64 userd_addr;
+ u64 mthdbuf_addr;
+ struct nvkm_vmm *vmm;
+ u64 gpfifo_offset;
+ u32 gpfifo_length;
+};
+
struct nvkm_rm_api {
const struct nvkm_rm_api_gsp {
int (*libos_init)(struct nvkm_gsp *);
@@ -113,9 +126,7 @@ struct nvkm_rm_api {
int (*rc_triggered)(void *priv, u32 fn, void *repv, u32 repc);
struct {
int (*alloc)(struct nvkm_gsp_device *, u32 handle,
- u32 nv2080_engine_type, u8 runq, bool priv, int chid,
- u64 inst_addr, u64 userd_addr, u64 mthdbuf_addr,
- struct nvkm_vmm *, u64 gpfifo_offset, u32 gpfifo_length,
+ const struct nvkm_rm_chan_alloc_args *chan_args,
struct nvkm_gsp_object *);
} chan;
} *fifo;
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
` (3 preceding siblings ...)
2026-07-29 4:15 ` [PATCH 4/6] nouveau/gsp: refactor the chan allocation arguments into a struct Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
2026-07-29 4:29 ` sashiko-bot
2026-07-29 4:15 ` [PATCH 6/6] nouveau: set wpr boost flags like open driver does Dave Airlie
5 siblings, 1 reply; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
This just adds the pci io bar, link cap and os page size to the r570.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
drivers/gpu/drm/nouveau/include/nvkm/core/device.h | 2 ++
drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c | 13 +++++++++++++
.../gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 5 +++++
3 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
index 954a89d43bad..68b2d8a0b78c 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/device.h
@@ -86,6 +86,7 @@ enum nvkm_bar_id {
NVKM_BAR0_PRI,
NVKM_BAR1_FB,
NVKM_BAR2_INST,
+ NVKM_BAR3_IO,
};
struct nvkm_device_func {
@@ -99,6 +100,7 @@ struct nvkm_device_func {
resource_size_t (*resource_addr)(struct nvkm_device *, enum nvkm_bar_id);
resource_size_t (*resource_size)(struct nvkm_device *, enum nvkm_bar_id);
bool cpu_coherent;
+ int (*link_cap)(struct nvkm_device *, u32 *lnk_cap);
};
struct nvkm_device_quirk {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
index 248623b91e29..7cfa21d9abaa 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
@@ -1576,6 +1576,10 @@ nvkm_device_pci_resource_idx(struct nvkm_device_pci *pdev, enum nvkm_bar_id bar)
if (bar == NVKM_BAR2_INST)
return idx;
+ idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1;
+ if (bar == NVKM_BAR3_IO)
+ return idx;
+
WARN_ON(1);
return -1;
}
@@ -1628,6 +1632,14 @@ nvkm_device_pci_preinit(struct nvkm_device *device)
return 0;
}
+static int
+nvkm_device_pci_link_cap(struct nvkm_device *device, u32 *lnk_cap)
+{
+ struct nvkm_device_pci *pdev = nvkm_device_pci(device);
+
+ return pcie_capability_read_dword(pdev->pdev, PCI_EXP_LNKCAP, lnk_cap);
+}
+
static void *
nvkm_device_pci_dtor(struct nvkm_device *device)
{
@@ -1646,6 +1658,7 @@ nvkm_device_pci_func = {
.resource_addr = nvkm_device_pci_resource_addr,
.resource_size = nvkm_device_pci_resource_size,
.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
+ .link_cap = nvkm_device_pci_link_cap,
};
int
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
index d9786830153d..857eda1e7439 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
@@ -165,6 +165,7 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp)
info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI);
info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB);
info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST);
+ info->gpuPhysIoAddr = device->func->resource_addr(device, NVKM_BAR3_IO);
info->nvDomainBusDeviceFunc = pci_dev_id(pdev);
info->maxUserVa = TASK_SIZE;
info->pciConfigMirrorBase = device->pci->func->cfg.addr;
@@ -175,6 +176,10 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp)
r570_gsp_acpi_info(gsp, &info->acpiMethodData);
info->bIsPrimary = video_is_primary_device(device->dev);
info->bPreserveVideoMemoryAllocations = false;
+ info->hostPageSize = PAGE_SIZE;
+
+ if (device->func->link_cap)
+ device->func->link_cap(device, &info->pcieConfigReg.linkCap);
return nvkm_gsp_rpc_wr(gsp, info, NVKM_GSP_RPC_REPLY_NOSEQ);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info
2026-07-29 4:15 ` [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info Dave Airlie
@ 2026-07-29 4:29 ` sashiko-bot
0 siblings, 0 replies; 10+ messages in thread
From: sashiko-bot @ 2026-07-29 4:29 UTC (permalink / raw)
To: Dave Airlie; +Cc: dri-devel
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The BAR index calculation for NVKM_BAR3_IO lacks bounds checking, leading to PCI ROM resource aliasing if all preceding BARs are 64-bit.
--
--- Patch [5]: [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info ---
commit 18c8db5e682be4972a386c192c00409e01054607
Author: Dave Airlie <airlied@redhat.com>
nouveau/gsp: add some more fields to r570 system info
This commit adds the pci io bar, link cap and os page size to the r570
system info.
> diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
> --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
[ ... ]
> @@ -1576,6 +1576,10 @@ nvkm_device_pci_resource_idx(struct nvkm_device_pci *pdev, enum nvkm_bar_id bar)
> if (bar == NVKM_BAR2_INST)
> return idx;
>
> + idx += (pci_resource_flags(pdev->pdev, idx) & IORESOURCE_MEM_64) ? 2 : 1;
> + if (bar == NVKM_BAR3_IO)
> + return idx;
[Severity: Medium]
Does this calculation lack a bounds check against PCI_STD_NUM_BARS?
If a GPU is configured with three 64-bit BARs (BAR0, BAR1, and BAR2), the
calculation idx += 2 will occur three times. This results in idx becoming 6.
Since index 6 corresponds to PCI_ROM_RESOURCE, could this cause the IO BAR
lookup to accidentally alias with the PCI Expansion ROM resource?
> +
> WARN_ON(1);
> return -1;
> }
[ ... ]
> diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> --- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
> +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
[ ... ]
> @@ -165,6 +165,7 @@ r570_gsp_set_system_info(struct nvkm_gsp *gsp)
> info->gpuPhysAddr = device->func->resource_addr(device, NVKM_BAR0_PRI);
> info->gpuPhysFbAddr = device->func->resource_addr(device, NVKM_BAR1_FB);
> info->gpuPhysInstAddr = device->func->resource_addr(device, NVKM_BAR2_INST);
> + info->gpuPhysIoAddr = device->func->resource_addr(device, NVKM_BAR3_IO);
[Severity: Medium]
If the above index calculation results in 6 due to having three 64-bit BARs,
this assignment will populate info->gpuPhysIoAddr with the physical address
of the PCI Expansion ROM instead of a non-existent IO BAR.
Could exposing this incorrect hardware layout cause undefined firmware
behavior or hardware faults if the GSP firmware attempts to access the
ROM address assuming it is an IO space?
> info->nvDomainBusDeviceFunc = pci_dev_id(pdev);
> info->maxUserVa = TASK_SIZE;
> info->pciConfigMirrorBase = device->pci->func->cfg.addr;
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260729041653.3985549-1-airlied@gmail.com?part=5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6/6] nouveau: set wpr boost flags like open driver does.
2026-07-29 4:15 nouveau/gsp: some r570 additions and refactoring Dave Airlie
` (4 preceding siblings ...)
2026-07-29 4:15 ` [PATCH 5/6] nouveau/gsp: add some more fields to r570 system info Dave Airlie
@ 2026-07-29 4:15 ` Dave Airlie
5 siblings, 0 replies; 10+ messages in thread
From: Dave Airlie @ 2026-07-29 4:15 UTC (permalink / raw)
To: dri-devel; +Cc: nouveau, dakr
From: Dave Airlie <airlied@redhat.com>
I think this might just boot GSP faster, but maybe it has some
other effects. This is only set on Turing/Ampere/Ada.
This corresponds to what the openrm drivers does.
Signed-off-by: Dave Airlie <airlied@redhat.com>
---
.../drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c | 3 +++
.../drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c | 17 +++++++++++++++++
.../nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h | 7 +++++++
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h | 2 ++
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c | 2 ++
5 files changed, 31 insertions(+)
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
index 77a5a1882472..6f1a934a6afe 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
@@ -1740,6 +1740,9 @@ r535_gsp_fini(struct nvkm_gsp *gsp, enum nvkm_suspend_state suspend)
sr->sysmemAddrOfSuspendResumeData = gsp->sr.radix3.lvl0.addr;
sr->sizeOfSuspendResumeData = len;
+ if (gsp->rm->api->gsp->set_sr_boost_flags)
+ gsp->rm->api->gsp->set_sr_boost_flags(gsp, sr, gsp->wpr_meta.data);
+
ret = rm->api->fbsr->suspend(gsp, suspend == NVKM_RUNTIME_SUSPEND);
if (ret) {
nvkm_gsp_mem_dtor(&gsp->sr.meta);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
index 857eda1e7439..5ff886485774 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/gsp.c
@@ -290,10 +290,27 @@ r570_gsp_libos_init(struct nvkm_gsp *gsp)
return 0;
}
+static void
+r570_gsp_set_wpr_boost_flags(struct nvkm_gsp *gsp, void *data)
+{
+ GspFwWprMeta *meta = data;
+ meta->flags = GSP_FW_FLAGS_CLOCK_BOOST;
+}
+
+static void
+r570_gsp_set_sr_boost_flags(struct nvkm_gsp *gsp, void *sr_ptr, void *meta_ptr)
+{
+ GspFwWprMeta *meta = meta_ptr;
+ GspFwSRMeta *sr = sr_ptr;
+ sr->flags = meta->flags;
+}
+
const struct nvkm_rm_api_gsp
r570_gsp = {
.libos_init = r570_gsp_libos_init,
.set_rmargs = r570_gsp_set_rmargs,
+ .set_wpr_boost_flags = r570_gsp_set_wpr_boost_flags,
+ .set_sr_boost_flags = r570_gsp_set_sr_boost_flags,
.set_system_info = r570_gsp_set_system_info,
.get_static_info = r570_gsp_get_static_info,
.xlat_mc_engine_idx = r570_gsp_xlat_mc_engine_idx,
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
index 23c30cbdefff..895ed3b85c31 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r570/nvrm/gsp.h
@@ -494,6 +494,13 @@ typedef struct
#define GSP_FW_WPR_META_REVISION 1
+#define GSP_FW_FLAGS 8:0
+#define GSP_FW_FLAGS_CLOCK_BOOST BIT(0)
+#define GSP_FW_FLAGS_RECOVERY_MARGIN_PRESENT BIT(1)
+#define GSP_FW_FLAGS_PPCIE_ENABLED BIT(2)
+#define GSP_FW_FLAGS_MULTI_GPU_NVLE_ENABLED BIT(3)
+#define GSP_FW_FLAGS_SCAN_RECOVERY_MARGIN BIT(4)
+
typedef struct {
NvU64 sharedMemPhysAddr;
NvU32 pageTableEntryCount;
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
index b71ba74eec12..e8231a589e56 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/rm.h
@@ -48,6 +48,8 @@ struct nvkm_rm_api {
const struct nvkm_rm_api_gsp {
int (*libos_init)(struct nvkm_gsp *);
void (*set_rmargs)(struct nvkm_gsp *, bool resume);
+ void (*set_wpr_boost_flags)(struct nvkm_gsp *, void *meta);
+ void (*set_sr_boost_flags)(struct nvkm_gsp *, void *sr, void *meta);
int (*set_system_info)(struct nvkm_gsp *);
int (*get_static_info)(struct nvkm_gsp *);
bool (*xlat_mc_engine_idx)(u32 mc_engine_idx, enum nvkm_subdev_type *, int *inst);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
index 11a37963bd4e..5cb65fc0dc9f 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/tu102.c
@@ -224,6 +224,8 @@ tu102_gsp_wpr_meta_init(struct nvkm_gsp *gsp)
meta->magic = GSP_FW_WPR_META_MAGIC;
meta->revision = GSP_FW_WPR_META_REVISION;
+ if (gsp->rm->api->gsp->set_wpr_boost_flags)
+ gsp->rm->api->gsp->set_wpr_boost_flags(gsp, meta);
meta->sysmemAddrOfRadix3Elf = gsp->radix3.lvl0.addr;
meta->sizeOfRadix3Elf = gsp->fb.wpr2.elf.size;
--
2.55.0
^ permalink raw reply related [flat|nested] 10+ messages in thread