summaryrefslogtreecommitdiffstats
path: root/kernel/main.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-24 02:29:04 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-09-24 02:29:04 -0400
commit2849119d1512dc5f6c9ca05976473148fbc88481 (patch)
tree17745c1a4390a4f2139aec21c8f5971404d92116 /kernel/main.c
parent3b9432714a0515b89309ff2e6c1983690fb67761 (diff)
downloadopen-iov-2849119d1512dc5f6c9ca05976473148fbc88481.tar.gz
open-iov-2849119d1512dc5f6c9ca05976473148fbc88481.zip
kernel: completion-event hints and GSP-RM state introspection
- re-post the completion event for a bounded window after a channel completes work (notifier consumed or semaphore release applied), so a client that starts waiting after the edge-triggered wake-up still gets a wake-up; the OS event classes carry no source object, so the hint broadcasts to the registered events - add rmstate (dump msgq cursors, guest consumption position, event table) and rmpost (post an event record by index or to all) debug parameters, both executing in kthreads because the IOMMU read path only works with a NULL current->mm or the mapping owner's mm - report the underlying error codes from the event post path
Diffstat (limited to 'kernel/main.c')
-rw-r--r--kernel/main.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/kernel/main.c b/kernel/main.c
index 05a49b1..25bd5eb 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -3023,5 +3023,104 @@ static const struct kernel_param_ops nv_vgpu_inject_irq_ops = {
module_param_cb(inject_irq, &nv_vgpu_inject_irq_ops, NULL, 0200);
MODULE_PARM_DESC(inject_irq, "Deliver MSI-X vector N to the guest (debug)");
+/*
+ * Debug: dump the GSP-RM msgq cursors (ours and the guest's) plus the
+ * registered event objects:
+ * echo 1 > .../parameters/rmstate
+ *
+ * Runs in a kthread: vfio_iommu_type1_dma_rw only works when current->mm is
+ * NULL (kthread) or matches the mapping's mm (QEMU).
+ */
+static int nv_vgpu_rmstate_thread(void *arg)
+{
+ struct completion *done = arg;
+ struct nv_vgpu_device *vgpu;
+
+ mutex_lock(&nv_vgpu_driver.lock);
+ list_for_each_entry(vgpu, &nv_vgpu_driver.devices, list) {
+ if (atomic_read(&vgpu->vfio_dev_open_count) <= 0)
+ continue;
+ gsp_rm_dump_state(vgpu);
+ }
+ mutex_unlock(&nv_vgpu_driver.lock);
+
+ complete(done);
+ return 0;
+}
+
+static int nv_vgpu_rmstate_set(const char *val, const struct kernel_param *kp)
+{
+ DECLARE_COMPLETION_ONSTACK(done);
+ struct task_struct *task;
+
+ task = kthread_run(nv_vgpu_rmstate_thread, &done, "vgpu-rmstate");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ wait_for_completion(&done);
+ return 0;
+}
+
+static const struct kernel_param_ops nv_vgpu_rmstate_ops = {
+ .set = nv_vgpu_rmstate_set,
+};
+
+module_param_cb(rmstate, &nv_vgpu_rmstate_ops, NULL, 0200);
+MODULE_PARM_DESC(rmstate, "Dump GSP-RM msgq cursors and event table (debug)");
+
+/*
+ * Debug: post an event record to the guest (idx < events_n, or 0xffffffff
+ * for every registered event):
+ * echo 0 > .../parameters/rmpost
+ */
+struct nv_vgpu_rmpost_req {
+ u32 idx;
+ int rc;
+ struct completion done;
+};
+
+static int nv_vgpu_rmpost_thread(void *arg)
+{
+ struct nv_vgpu_rmpost_req *req = arg;
+ struct nv_vgpu_device *vgpu;
+
+ mutex_lock(&nv_vgpu_driver.lock);
+ list_for_each_entry(vgpu, &nv_vgpu_driver.devices, list) {
+ if (atomic_read(&vgpu->vfio_dev_open_count) <= 0)
+ continue;
+ req->rc = gsp_rm_force_post(vgpu, req->idx);
+ pr_info("gsp-resman-vfio: rmpost idx=%u -> %d\n",
+ req->idx, req->rc);
+ }
+ mutex_unlock(&nv_vgpu_driver.lock);
+
+ complete(&req->done);
+ return 0;
+}
+
+static int nv_vgpu_rmpost_set(const char *val, const struct kernel_param *kp)
+{
+ static struct nv_vgpu_rmpost_req req;
+ struct task_struct *task;
+
+ memset(&req, 0, sizeof(req));
+ req.rc = -ENODEV;
+ if (kstrtou32(val, 0, &req.idx))
+ return -EINVAL;
+
+ init_completion(&req.done);
+ task = kthread_run(nv_vgpu_rmpost_thread, &req, "vgpu-rmpost");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ wait_for_completion(&req.done);
+ return 0;
+}
+
+static const struct kernel_param_ops nv_vgpu_rmpost_ops = {
+ .set = nv_vgpu_rmpost_set,
+};
+
+module_param_cb(rmpost, &nv_vgpu_rmpost_ops, NULL, 0200);
+MODULE_PARM_DESC(rmpost, "Post a GSP-RM event to the guest by event index (debug)");
+
module_init(nv_vgpu_init);
module_exit(nv_vgpu_exit);