diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-05 12:47:47 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-10-05 12:47:47 -0400 |
| commit | 0f227d063e281c4b8ec21e61132ae1ddf0920053 (patch) | |
| tree | aba72956d7ab9d6cb69212696f56091af77281ab /kernel | |
| parent | 708a3802824358c1770d5ad0b3c2e24fae114eb8 (diff) | |
| download | open-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')
| -rw-r--r-- | kernel/bar_emulation.c | 17 | ||||
| -rw-r--r-- | kernel/main.c | 21 |
2 files changed, 25 insertions, 13 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); } /* diff --git a/kernel/main.c b/kernel/main.c index a5a64fd..f662b94 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -85,10 +85,13 @@ static unsigned int nv_vgpu_get_available(struct mdev_type *mtype) const char *name = mtype->sysfs_name; unsigned int active = 0, max = 1; - /* Type dirs may carry an extra "nvidia-" prefix vs our type names */ - if (str_has_prefix(name, "nvidia-")) - name += strlen("nvidia-"); - info = nv_vgpu_find_type_info(name); + /* + * sysfs_name is our registered type name verbatim ("nvidia-vgpu-*"). + * The mdev core prefixes only the type DIRECTORY with the parent + * driver string (mdev_type_add: "%s-%s", dev_driver_string, sysfs_name); + * it does not touch sysfs_name. Match it directly. + */ + info = name ? nv_vgpu_find_type_info(name) : NULL; if (info && info->max_instances) max = info->max_instances; @@ -116,8 +119,7 @@ static ssize_t nv_vgpu_show_description(struct mdev_type *mtype, char *buf) const char *name = mtype->sysfs_name; u32 vram_mb = 512, max_inst = 1; - if (name && str_has_prefix(name, "nvidia-")) - name += strlen("nvidia-"); + /* sysfs_name is the registered type name; match it directly. */ info = name ? nv_vgpu_find_type_info(name) : NULL; if (info) { if (info->vram_mb) @@ -563,15 +565,14 @@ static int nv_vgpu_mdev_create(struct mdev_device *mdev) vgpu->state = NV_VGPU_STATE_UNINITIALIZED; /* * Bind the emulated FB size to this mdev's type (the type's vram_mb; - * 0/absent keeps the 512 MiB default). The type dir may carry an - * extra "nvidia-" prefix vs our registered names. + * 0/absent keeps the 512 MiB default). sysfs_name is the registered + * type name verbatim; match it directly (the mdev core only prefixes + * the type directory with the parent driver string). */ { const char *tname = mdev->type ? mdev->type->sysfs_name : NULL; struct nv_vgpu_type_info *tinfo; - if (tname && str_has_prefix(tname, "nvidia-")) - tname += strlen("nvidia-"); tinfo = tname ? nv_vgpu_find_type_info(tname) : NULL; vgpu->fb_emul_size = (tinfo && tinfo->vram_mb) ? (u64)tinfo->vram_mb << 20 : NV_VGPU_EMUL_FB_SIZE; |
