Skip to content

NVIDIA: SAUCE: target/arm: Add sysfs detection for KVM CCA capability#12

Closed
ianm-nv wants to merge 1 commit intoNVIDIA:nvidia_unstable-10.1from
ianm-nv:nvidia_unstable-10.1+cca/dev
Closed

NVIDIA: SAUCE: target/arm: Add sysfs detection for KVM CCA capability#12
ianm-nv wants to merge 1 commit intoNVIDIA:nvidia_unstable-10.1from
ianm-nv:nvidia_unstable-10.1+cca/dev

Conversation

@ianm-nv
Copy link
Copy Markdown
Collaborator

@ianm-nv ianm-nv commented Feb 9, 2026

Add runtime detection of the KVM CCA capability number by reading from the kernel's sysfs module parameter. This allows QEMU to automatically discover the correct capability number without needing version-specific hardcoded values that may become stale.

The ARM CCA host patches underwent a naming change from RME to RMI in v11:

  • v10 (Linux 6.17): KVM_CAP_ARM_RME, sysfs param kvm_cap_arm_rme
  • v11 (Linux 6.18+): KVM_CAP_ARM_RMI, sysfs param kvm_cap_arm_rmi

Detection order:

  1. Try v11 sysfs path (/sys/module/kvm/parameters/kvm_cap_arm_rmi)
  2. Try v10 sysfs path (/sys/module/kvm/parameters/kvm_cap_arm_rme)
  3. Fall back to uname detection for 6.16 dev kernel (capability == 243)
  4. Use compile-time KVM_CAP_ARM_RME as last resort

This allows the same QEMU binary to work with linux-nvidia-6.16 (dev), linux-nvidia-6.17 (v10 host patches), and linux-nvidia-6.18+ (v11 host patches).

Here is a ref to the kernel patch that enables the sysfs capability.

I've tested this with the following kernels:
6.16-pset
6.17-nvidia-devel
6.17-nvidia
6.18-nvidia

Add runtime detection of the KVM CCA capability number by reading from
the kernel's sysfs module parameter. This allows QEMU to automatically
discover the correct capability number without needing version-specific
hardcoded values that may become stale.

The ARM CCA host patches underwent a naming change from RME to RMI in v11:
  - v10 (Linux 6.17): KVM_CAP_ARM_RME, sysfs param kvm_cap_arm_rme
  - v11 (Linux 6.18+): KVM_CAP_ARM_RMI, sysfs param kvm_cap_arm_rmi

Detection order:
  1. Try v11 sysfs path (/sys/module/kvm/parameters/kvm_cap_arm_rmi)
  2. Try v10 sysfs path (/sys/module/kvm/parameters/kvm_cap_arm_rme)
  3. Fall back to uname detection for 6.16 dev kernel (capability == 243)
  4. Use compile-time KVM_CAP_ARM_RME as last resort

This allows the same QEMU binary to work with linux-nvidia-6.16 (dev),
linux-nvidia-6.17 (v10 host patches), and linux-nvidia-6.18+ (v11 host
patches).

Signed-off-by: Ian May <ianm@nvidia.com>
Copy link
Copy Markdown
Collaborator

@nvmochs nvmochs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Acked-by: Matthew R. Ochs <mochs@nvidia.com>

Copy link
Copy Markdown
Collaborator

@NathanChenNVIDIA NathanChenNVIDIA left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Acked-by: Nathan Chen nathanc@nvidia.com

@nvmochs
Copy link
Copy Markdown
Collaborator

nvmochs commented Feb 10, 2026

Merged, closing PR.

@nvmochs nvmochs closed this Feb 10, 2026
JiandiAnNVIDIA pushed a commit that referenced this pull request Mar 31, 2026
Commit e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory
region") made the name member of MemoryRegion unset, causing a NULL
pointer dereference[1]:
> Thread 2 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
> (gdb) bt
> #0  0x00007ffff56565e2 in __strcmp_evex () at /lib64/libc.so.6
> #1  0x0000555555841bdb in find_fd (head=0x5555572337d0 <cpr_state>,
> name=0x0, id=0) at ../migration/cpr.c:68
> #2  cpr_delete_fd (name=name@entry=0x0, id=id@entry=0) at
> ../migration/cpr.c:77
> #3  0x000055555582290a in qemu_ram_free (block=0x7ff7e93aa7f0) at
> ../system/physmem.c:2615
> #4  0x000055555581ae02 in memory_region_finalize (obj=<optimized out>)
> at ../system/memory.c:1816
> #5  0x0000555555a70ab9 in object_deinit (obj=<optimized out>,
> type=<optimized out>) at ../qom/object.c:715
> #6  object_finalize (data=0x7ff7e936eff0) at ../qom/object.c:729
> #7  object_unref (objptr=0x7ff7e936eff0) at ../qom/object.c:1232
> #8  0x0000555555814fae in memory_region_unref (mr=<optimized out>) at
> ../system/memory.c:1848
> #9  flatview_destroy (view=0x555559ed6c40) at ../system/memory.c:301
> #10 0x0000555555bfc122 in call_rcu_thread (opaque=<optimized out>) at
> ../util/rcu.c:324
> #11 0x0000555555bf17a7 in qemu_thread_start (args=0x555557b99520) at
> ../util/qemu-thread-posix.c:393
> #12 0x00007ffff556f464 in start_thread () at /lib64/libc.so.6
> #13 0x00007ffff55f25ac in __clone3 () at /lib64/libc.so.6

The intention of the aforementioned commit is to prevent a MemoryRegion
from parenting itself while its references is counted indendependently
of the device. To achieve the same goal, add a type of QOM objects that
count references and parent MemoryRegions.

[1] https://lore.kernel.org/qemu-devel/4eb93d7a-1fa9-4b3c-8ad7-a2eb64f025a0@collabora.com/

Cc: qemu-stable@nongnu.org
Fixes: e27194e087ae ("virtio-gpu-virgl: correct parent for blob memory region")
Fixes: be88ad4 ("virtio-gpu-virgl: correct parent for blob memory region") for 10.2.x
Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Tested-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Tested-by: Joelle van Dyne <j@getutm.app>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-Id: <20260214-region-v1-1-229f00ae1f38@rsg.ci.i.u-tokyo.ac.jp>
(cherry picked from commit b2a279094c3b86667969cc645f7fb1087e08dd19)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
JiandiAnNVIDIA pushed a commit that referenced this pull request Mar 31, 2026
The test case in the ppe42 functional test triggers a TCG debug
assertion, which causes the test to fail in an --enable-debug
build or when the sanitizers are enabled:

#6  0x00007ffff4a3b517 in __assert_fail
    (assertion=0x5555562e7589 "!temp_readonly(ots)", file=0x5555562e5b23 "../../tcg/tcg.c", line=4928, function=0x5555562e8900 <__PRETTY_FUNCTION__.23> "tcg_reg_alloc_mov") at ./assert/assert.c:105
#7  0x0000555555cc2189 in tcg_reg_alloc_mov (s=0x7fff60000b70, op=0x7fff600126f8) at ../../tcg/tcg.c:4928
#8  0x0000555555cc74e0 in tcg_gen_code (s=0x7fff60000b70, tb=0x7fffa802f540, pc_start=4294446080) at ../../tcg/tcg.c:6667
#9  0x0000555555d02abe in setjmp_gen_code
    (env=0x555556cbe610, tb=0x7fffa802f540, pc=4294446080, host_pc=0x7fffeea00c00, max_insns=0x7fffee9f9d74, ti=0x7fffee9f9d90)
    at ../../accel/tcg/translate-all.c:257
#10 0x0000555555d02d75 in tb_gen_code (cpu=0x555556cba590, s=...) at ../../accel/tcg/translate-all.c:325
#11 0x0000555555cf5922 in cpu_exec_loop (cpu=0x555556cba590, sc=0x7fffee9f9ee0) at ../../accel/tcg/cpu-exec.c:970
#12 0x0000555555cf5aae in cpu_exec_setjmp (cpu=0x555556cba590, sc=0x7fffee9f9ee0) at ../../accel/tcg/cpu-exec.c:1016
#13 0x0000555555cf5b4b in cpu_exec (cpu=0x555556cba590) at ../../accel/tcg/cpu-exec.c:1042
#14 0x0000555555d1e7ab in tcg_cpu_exec (cpu=0x555556cba590) at ../../accel/tcg/tcg-accel-ops.c:82
#15 0x0000555555d1ff97 in rr_cpu_thread_fn (arg=0x555556cba590) at ../../accel/tcg/tcg-accel-ops-rr.c:285
#16 0x00005555561586c9 in qemu_thread_start (args=0x555556ee3c90) at ../../util/qemu-thread-posix.c:393
#17 0x00007ffff4a9caa4 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#18 0x00007ffff4b29c6c in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

This can be reproduced "by hand":

 ./build/clang/qemu-system-ppc -display none -vga none \
    -machine ppe42_machine -serial stdio \
    -device loader,file=$HOME/.cache/qemu/download/03c1ac0fb7f6c025102a02776a93b35101dae7c14b75e4eab36a337e39042ea8 \
    -device loader,addr=0xfff80040,cpu-num=0

(assuming you have the image file from the functional test
in your local cache).

This happens for this input:

IN:
0xfff80c00:  07436004  .byte    0x07, 0x43, 0x60, 0x04

which generates (among other things):

 not_i32 $0x80000,$0x80000

which the TCG optimization pass turns into:

 mov_i32 $0x80000,$0xfff7ffff             dead: 1  pref=0xffff

and where we then assert because we tried to write to a constant.

This happens for the CLRBWIBC instruction which ends up in
do_mask_branch() with rb_is_gpr false and invert true.  In this case
we will generate code that sets mask to a tcg_constant_tl() but then
uses it as the LHS in tcg_gen_not_tl().

Fix the assertion by doing the invert in the translate time C code
for the "mask is constant" case.

Cc: qemu-stable@nongnu.org
Fixes: f7ec91c ("target/ppc: Add IBM PPE42 special instructions")
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Glenn Miles <milesg@linux.ibm.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Link: https://lore.kernel.org/qemu-devel/20260212150753.1749448-1-peter.maydell@linaro.org
Signed-off-by: Harsh Prateek Bora <harshpb@linux.ibm.com>
(cherry picked from commit 78c6b6010ce7cfa54874dda514e694640b76f1e4)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants