summaryrefslogtreecommitdiffstats
path: root/kernel/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/main.c')
-rw-r--r--kernel/main.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/kernel/main.c b/kernel/main.c
index 2ec7ab9..84a05ca 100644
--- a/kernel/main.c
+++ b/kernel/main.c
@@ -2628,6 +2628,44 @@ module_param_cb(dump_vidmem, &nv_vgpu_dump_vidmem_ops, NULL, 0200);
MODULE_PARM_DESC(dump_vidmem, "Dump emulated vidmem range (hex offset,hex len)");
/*
+ * Debug: write a u32 into the emulated vidmem (BAR1 backing) at an offset:
+ * echo 0x<offset>,0x<value> > .../parameters/poke_vidmem
+ */
+static int nv_vgpu_poke_vidmem_set(const char *val, const struct kernel_param *kp)
+{
+ struct nv_vgpu_device *vgpu;
+ u64 off = 0, value = 0;
+ char *end;
+ int ret = 0;
+
+ if (sscanf(val, "%lli,%lli", &off, &value) != 2)
+ return -EINVAL;
+
+ 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;
+ if (!vgpu->bars[1].vaddr || off + 4 > vgpu->bars[1].size) {
+ ret = -EINVAL;
+ break;
+ }
+ memcpy(vgpu->bars[1].vaddr + off, &value, 4);
+ pr_info("poke_vidmem: [0x%llx] = 0x%llx\n", off, value);
+ break;
+ }
+ mutex_unlock(&nv_vgpu_driver.lock);
+ (void)end;
+ return ret;
+}
+
+static const struct kernel_param_ops nv_vgpu_poke_vidmem_ops = {
+ .set = nv_vgpu_poke_vidmem_set,
+};
+
+module_param_cb(poke_vidmem, &nv_vgpu_poke_vidmem_ops, NULL, 0200);
+MODULE_PARM_DESC(poke_vidmem, "Write u32 to emulated vidmem (hex offset,hex value)");
+
+/*
* Debug: hex-dump a guest physical range (kthread: guest-DMA needs it):
* echo 0x<gpa>,0x<len> > .../parameters/dump_guest
*/