summaryrefslogtreecommitdiffstats
path: root/kernel/bar_emulation.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 12:47:47 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-05 12:47:47 -0400
commit0f227d063e281c4b8ec21e61132ae1ddf0920053 (patch)
treeaba72956d7ab9d6cb69212696f56091af77281ab /kernel/bar_emulation.c
parent708a3802824358c1770d5ad0b3c2e24fae114eb8 (diff)
downloadopen-iov-0f227d063e281c4b8ec21e61132ae1ddf0920053.tar.gz
open-iov-0f227d063e281c4b8ec21e61132ae1ddf0920053.zip
vgsp: fix per-type VRAM type lookup and canonical FB-size encoding
The 708a3802 per-type VRAM change stripped an nvidia- prefix from mdev->type->sysfs_name, but sysfs_name is the registered type name verbatim; the mdev core only prefixes the type DIRECTORY with the parent driver string. Every lookup failed, so all mdevs silently fell back to 512 MiB, nvidia-vgpu-turing-1g was unreachable and available_instances capped at 1. Match sysfs_name directly in get_available, show_description and mdev_create. Also canonicalise the NV_PFB_PRI_MMU_LOCAL_MEMORY_RANGE encoder (BAR0+0x100ce0) by stripping factors of two from MAG so 512 MiB encodes 0x19 again (1 GiB 0x1a, 2 GiB 0x1b) instead of the non-canonical 0x204. Default-512M behaviour is now byte-equivalent to the known-good pre-VRAM module except max_instances=2. Module sha256 cb1724d3.
Diffstat (limited to 'kernel/bar_emulation.c')
-rw-r--r--kernel/bar_emulation.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/kernel/bar_emulation.c b/kernel/bar_emulation.c
index 8e3f8cf..d1702c8 100644
--- a/kernel/bar_emulation.c
+++ b/kernel/bar_emulation.c
@@ -290,13 +290,24 @@ int nv_vgpu_bar_emul_init(struct nv_vgpu_device *vgpu)
* guest's fbSize - reserved arithmetic stays consistent.
*/
u64 fb = nv_vgpu_fb_emul_size(ctx->vgpu);
- u32 scale = 0;
+ u32 scale = 0, mag;
+ /*
+ * Find the largest SCALE whose MAG fits the 6-bit field, then
+ * canonicalise: strip factors of two from MAG while SCALE can
+ * absorb them. 512 MiB -> mag=1,scale=9 -> 0x19 (the historical
+ * known-good value); 1 GiB -> 0x1a; 2 GiB -> 0x1b. Sizes that
+ * are not exactly representable round down.
+ */
while (scale < 15 && (fb >> (scale + 20)) > 0x3f)
scale++;
+ mag = (u32)(fb >> (scale + 20));
+ while (scale < 15 && mag > 1 && !(mag & 1u)) {
+ mag >>= 1;
+ scale++;
+ }
*(u32 *)((u8 *)ctx->bar0_shadow + 0x100ce0) =
- ((((u32)(fb >> (scale + 20))) & 0x3f) << 4) |
- (scale & 0xf);
+ ((mag & 0x3f) << 4) | (scale & 0xf);
}
/*