summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/gsp_phys_booter.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/kernel/gsp_phys_booter.c b/kernel/gsp_phys_booter.c
index 3ba8714..fa2d3b4 100644
--- a/kernel/gsp_phys_booter.c
+++ b/kernel/gsp_phys_booter.c
@@ -248,6 +248,18 @@ bool gsp_phys_boot_requested(void)
#define GSP_PHYS_RMCALL_OS32_TYPE_IMAGE 0u
#define GSP_PHYS_RMCALL_OS32_ATTR_VIDMEM_UNCACHED 0u
+/* Owner of the notifier allocation. NV_MEMORY_ALLOCATION_PARAMS.owner may not
+ * be 0, 0xFFFFFFFF or an RM scratch owner
+ * [HEAP_OWNER_RM_SCRATCH_BEGIN=0xDEAF0000, ..._END=0xDEAF0009]
+ * (standard_mem.c:73-79), and the reference notifier allocation uses
+ * HEAP_OWNER_RM_CLIENT_GENERIC = HEAP_OWNER_RM_SCRATCH_END + 3 = 0xDEAF000C
+ * (g_heap_nvoc.h:168-181; mem_utils_gm107.c:348-355). */
+#define GSP_PHYS_RMCALL_HEAP_OWNER_RM_CLIENT_GENERIC 0xDEAF000Cu
+
+/* NVOS32_ALLOC_INTERNAL_FLAGS_SKIP_SCRUB (nvos.h:1511), used by the reference
+ * notifier allocation (mem_utils_gm107.c:355). */
+#define GSP_PHYS_RMCALL_OS32_INTERNAL_FLAG_SKIP_SCRUB 0x4u
+
/*
* FERMI_VASPACE_A allocation (nvos.h:2756-2765): flags bit 3
* (IS_EXTERNALLY_OWNED) and bit 8 (ALLOW_ZERO_ADDRESS); the 256 MB window is
@@ -4247,7 +4259,8 @@ struct gsp_phys_rmcall_mem_desc {
* are 8-byte aligned; offset and limit are [IN/OUT], so a frame-buffer
* allocation returns the allocated FB offset (and its limit) in the echoed
* params. type/attr carry the NVOS32 enums (type IMAGE, location VIDMEM,
- * coherency UNCACHED are all the zero/default values).
+ * coherency UNCACHED are all the zero/default values); owner and internalflags
+ * must be nonzero for the class-0x40 constructor (see the notifier alloc).
*/
struct gsp_phys_rmcall_memory_alloc_params {
__le32 owner;
@@ -4646,10 +4659,12 @@ static int gsp_phys_rmcall_register_mem(void __iomem *bar0, u32 index)
* frame-buffer pages a guest already owns; 0x82 would accept our host PFNs as
* literal FB offsets). The frame-buffer page is therefore allocated from the
* GSP-RM itself with GSP_RM_ALLOC (103) class NV01_MEMORY_LOCAL_USER (0x40),
- * mirroring the RM's own channel-notifier allocation (type IMAGE, location
- * VIDMEM, coherency UNCACHED; mem_utils_gm107.c:344-352); the server returns
- * the allocated FB offset in NV_MEMORY_ALLOCATION_PARAMS.offset, which is what
- * errorNotifierMem.base carries.
+ * mirroring the RM's own channel-notifier allocation (owner
+ * HEAP_OWNER_RM_CLIENT_GENERIC, type IMAGE, location VIDMEM, coherency
+ * UNCACHED, internal flag SKIP_SCRUB; mem_utils_gm107.c:344-355); the server
+ * returns the allocated FB offset in NV_MEMORY_ALLOCATION_PARAMS.offset, which
+ * is what errorNotifierMem.base carries. A zero owner is rejected with
+ * NV_ERR_INVALID_OWNER (0x39) at standard_mem.c:73-79 (the cycle-20 failure).
*
* Failure is non-fatal: the channel alloc then keeps a zeroed notifier
* memdesc (server SYSMEM/ADDR_UNKNOWN, the cycle-19 shape) and the stage-4
@@ -4668,9 +4683,12 @@ static int gsp_phys_rmcall_alloc_notifier_mem(void __iomem *bar0)
int ret;
memset(&mem, 0, sizeof(mem));
+ mem.owner = cpu_to_le32(GSP_PHYS_RMCALL_HEAP_OWNER_RM_CLIENT_GENERIC);
mem.type = cpu_to_le32(GSP_PHYS_RMCALL_OS32_TYPE_IMAGE);
mem.size = cpu_to_le64(GSP_PHYS_RMCALL_NOTIFIER_SIZE);
mem.attr = cpu_to_le32(GSP_PHYS_RMCALL_OS32_ATTR_VIDMEM_UNCACHED);
+ mem.internalflags =
+ cpu_to_le32(GSP_PHYS_RMCALL_OS32_INTERNAL_FLAG_SKIP_SCRUB);
req = kvzalloc(req_len, GFP_KERNEL);
if (!req)
@@ -5246,7 +5264,8 @@ static u32 gsp_phys_rmcall_build_methods(u32 *pb, u64 sem_dma, u64 src_dma,
* membership, kernel_fifo_tu102.c:110-116; GPFIFO_SCHEDULE alone only sets
* RUNLIST_SET at kernel_channel.c:3244), and SET_NOTIF_INDEX (index 3 for
* subdevice 0, nvidia-push-init.c:303-316) gives the FBMEM notifier write a
- * target slot. Every control failure logs its rpc_result/status and aborts
+ * target slot; it is advisory here because no error-context object exists.
+ * Every other control failure logs its rpc_result/status and aborts
* before the doorbell; a 0x40 GET_WORK_SUBMIT_TOKEN whose echoed params carry
* a nonzero token still proceeds (the server writes the token before the
* notifier update, kernel_channel.c:3471-3477).
@@ -5320,7 +5339,14 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0)
return ret;
}
- /* (c) SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX (nvidia-push-init.c:303-316). */
+ /*
+ * (c) SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX (nvidia-push-init.c:303-316).
+ * Advisory, not fatal: with no error-context object (hErrorContext=0)
+ * the server's memory and ctxdma lookups both fail and it returns
+ * NV_ERR_OBJECT_NOT_FOUND (kernel_channel.c:4180). GET_WORK_SUBMIT_TOKEN
+ * generates and echoes the token before the notifier update, so the
+ * token path does not depend on this call (kernel_channel.c:3471-3477).
+ */
rpc_result = 0;
status = 0;
ret = gsp_phys_rmcall_control(bar0, boot_stage.rmcall_channel,
@@ -5328,11 +5354,12 @@ static int gsp_phys_rmcall_stage4(void __iomem *bar0)
&notif_index, sizeof(notif_index), 16,
NULL, 0, &rpc_result, &status,
"SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX");
- if (ret) {
- pr_err("gsp-phys-boot: rm-call: stage 4 aborted before the doorbell: SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX (0xc36f010a index=%u) failed (rpc_result=0x%x status=0x%x)\n",
- notif_index, rpc_result, status);
- return ret;
- }
+ if (ret)
+ pr_warn("gsp-phys-boot: rm-call: SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX (0xc36f010a index=%u) advisory failure: rpc_result=0x%x status=0x%x (no error-context object: hErrorContext=0); the work-submit token is generated independently of the notifier, continuing to GET_WORK_SUBMIT_TOKEN\n",
+ notif_index, rpc_result, status);
+ else
+ pr_info("gsp-phys-boot: rm-call: SET_WORK_SUBMIT_TOKEN_NOTIF_INDEX 0xc36f010a index=%u accepted (rpc_result=0x%x status=0x%x)\n",
+ notif_index, rpc_result, status);
/*
* (d) GET_WORK_SUBMIT_TOKEN. The helper copies the echoed params into
@@ -6548,10 +6575,18 @@ static_assert(sizeof(struct gsp_phys_rmcall_mem_desc) == 24,
"NV_MEMORY_DESC_PARAMS must be 24 bytes");
static_assert(sizeof(struct gsp_phys_rmcall_memory_alloc_params) == 128,
"NV_MEMORY_ALLOCATION_PARAMS must be 128 bytes (reference ABI)");
+static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, owner) == 0,
+ "NV_MEMORY_ALLOCATION_PARAMS.owner must be at offset 0");
+static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, attr) == 24,
+ "NV_MEMORY_ALLOCATION_PARAMS.attr must be at offset 24");
static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, size) == 64,
"NV_MEMORY_ALLOCATION_PARAMS.size must be at offset 64");
static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, offset) == 80,
"NV_MEMORY_ALLOCATION_PARAMS.offset [IN/OUT] must be at offset 80");
+static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, h_va_space) == 108,
+ "NV_MEMORY_ALLOCATION_PARAMS.hVASpace must be at offset 108");
+static_assert(offsetof(struct gsp_phys_rmcall_memory_alloc_params, internalflags) == 112,
+ "NV_MEMORY_ALLOCATION_PARAMS.internalflags must be at offset 112");
static_assert(sizeof(struct gsp_phys_rmcall_vas_params) == 48,
"NV_VASPACE_ALLOCATION_PARAMETERS must be 48 bytes (reference ABI)");
static_assert(sizeof(struct gsp_phys_rmcall_pdb_params) == 32,