Daniel

On Fri, Jul 17, 2026 at 6:56 PM Daniel Henrique Barboza
<[email protected]> wrote:
>
>
>
> On 7/14/2026 4:56 AM, Subrahmanya Lingappa wrote:
> > Boot an RPMI-enabled RISC-V virt guest and exercise the initial HSM,
> > system suspend, and system reset paths.
> >
> > Signed-off-by: Subrahmanya Lingappa <[email protected]>
> > ---
> >   tests/functional/riscv64/meson.build       |   2 +
> >   tests/functional/riscv64/test_rpmi_virt.py | 172 +++++++++++++++++++++
> >   2 files changed, 174 insertions(+)
> >   create mode 100644 tests/functional/riscv64/test_rpmi_virt.py
> >
> > diff --git a/tests/functional/riscv64/meson.build 
> > b/tests/functional/riscv64/meson.build
> > index 5871211e89..619a0735fa 100644
> > --- a/tests/functional/riscv64/meson.build
> > +++ b/tests/functional/riscv64/meson.build
> > @@ -3,6 +3,7 @@
> >   test_riscv64_timeouts = {
> >     'boston' : 120,
> >     'tuxrun' : 120,
> > +  'rpmi_virt' : 300,
> >   }
> >
> >   tests_riscv64_system_quick = [
> > @@ -15,4 +16,5 @@ tests_riscv64_system_thorough = [
> >     'boston',
> >     'sifive_u',
> >     'tuxrun',
> > +  'rpmi_virt',
> >   ]
> > diff --git a/tests/functional/riscv64/test_rpmi_virt.py 
> > b/tests/functional/riscv64/test_rpmi_virt.py
> > new file mode 100644
> > index 0000000000..c0f96f7d8d
> > --- /dev/null
> > +++ b/tests/functional/riscv64/test_rpmi_virt.py
> > @@ -0,0 +1,172 @@
> > +#!/usr/bin/env python3
> > +#
> > +# RISC-V virt RPMI Linux guest integration tests
> > +#
> > +# Copyright (c) 2026 Ventana Micro Systems Inc.
>
> We can't add a Ventana copyright dated 2026.  Ventana as an entity ceased to
> exist December 2025.
>
>
> Everything else LGTM.  Thanks,
> Daniel
>
 missed it before,  Fixed in v4. I dropped the stale Ventana Micro
Systems Inc. copyright
  line from the functional test.

thanks,
subbu

>
> > +# Copyright (c) 2026 Qualcomm Technologies, Inc.
> > +#
> > +# Author:
> > +#  Subrahmanya Lingappa <[email protected]>
> > +#
> > +# SPDX-License-Identifier: GPL-2.0-or-later
> > +
> > +import os
> > +from pathlib import Path
> > +import subprocess
> > +import time
> > +
> > +from qemu_test import QemuSystemTest
> > +from qemu_test import exec_command
> > +from qemu_test import exec_command_and_wait_for_pattern
> > +from qemu_test import get_qemu_img
> > +from qemu_test import wait_for_console_pattern
> > +
> > +
> > +class RiscvVirtRpmiGuestTest(QemuSystemTest):
> > +    """Boot Linux and exercise RPMI-backed services through guest APIs.
> > +
> > +    This test intentionally keeps guest artifacts external. Set:
> > +
> > +      QEMU_TEST_RPMI_OPENSBI=/path/to/fw_jump.bin
> > +      QEMU_TEST_RPMI_KERNEL=/path/to/Image
> > +      QEMU_TEST_RPMI_ROOTFS=/path/to/rootfs.ext4
> > +
> > +    Exact RPMI packet command-ID coverage remains in riscv-rpmi qtests. 
> > This
> > +    functional test verifies Linux/OpenSBI integration paths visible from a
> > +    real guest without adding probe hooks to production RPMI sources.
> > +    """
> > +
> > +    timeout = 360
> > +    PROMPT = 'root@tuxtest:~#'
> > +
> > +    def _require_path(self, env_name):
> > +        value = os.getenv(env_name)
> > +        if not value:
> > +            self.skipTest(f'{env_name} is required')
> > +        path = Path(value)
> > +        if not path.exists():
> > +            self.skipTest(f'{env_name} does not exist: {path}')
> > +        return path
> > +
> > +    def setUp(self):
> > +        super().setUp()
> > +        self.opensbi = self._require_path('QEMU_TEST_RPMI_OPENSBI')
> > +        self.kernel = self._require_path('QEMU_TEST_RPMI_KERNEL')
> > +        self.rootfs = self._require_path('QEMU_TEST_RPMI_ROOTFS')
> > +        self.qemu_img = get_qemu_img(self)
> > +
> > +    def _create_rootfs_overlay(self):
> > +        overlay = Path(self.scratch_file('rootfs.qcow2'))
> > +        subprocess.run([
> > +            self.qemu_img, 'create', '-q', '-f', 'qcow2', '-F', 'raw',
> > +            '-b', str(self.rootfs), str(overlay),
> > +        ], check=True)
> > +        return overlay
> > +
> > +    def _boot_guest(self, smp=4):
> > +        self.set_machine('virt')
> > +        self.machine = 'virt,rpmi=on,aia=aplic-imsic'
> > +        rootfs_overlay = self._create_rootfs_overlay()
> > +
> > +        self.vm.set_console()
> > +        self.vm.add_args(
> > +            '-cpu', 'rv64',
> > +            '-smp', str(smp),
> > +            '-m', '1G',
> > +            '-bios', str(self.opensbi),
> > +            '-kernel', str(self.kernel),
> > +            '-append', 'printk.time=0 root=/dev/vda rw console=ttyS0 '
> > +                       'earlycon=sbi loglevel=8 no_console_suspend',
> > +            '-blockdev', 'driver=qcow2,file.driver=file,'
> > +                         f'file.filename={rootfs_overlay},node-name=hd0',
> > +            '-device', 'virtio-blk-device,drive=hd0',
> > +        )
> > +        self.vm.launch()
> > +
> > +    def _expect_rpmi_firmware_and_linux(self):
> > +        patterns = [
> > +            'Platform HSM Device         : rpmi-hsm',
> > +            'Platform Suspend Device     : rpmi-system-suspend',
> > +            'Standard SBI Extensions',
> > +            'susp',
> > +            'tuxtest login:',
> > +        ]
> > +        for pattern in patterns:
> > +            wait_for_console_pattern(self, pattern)
> > +        exec_command_and_wait_for_pattern(self, 'root', self.PROMPT)
> > +
> > +    def _run_marker_command(self, command, marker, failure_marker=None):
> > +        out = exec_command_and_wait_for_pattern(self, command, marker,
> > +                                                
> > failure_message=failure_marker)
> > +        self.assertIn(marker.encode(), out)
> > +        return out
> > +
> > +    def _validate_hsm_boot_start(self, online_cpus):
> > +        self._run_marker_command(
> > +            'echo RPMI_LINUX_HSM_START_BEGIN; '
> > +            'cat /sys/devices/system/cpu/present; '
> > +            'online=$(cat /sys/devices/system/cpu/online); '
> > +            'echo "$online"; '
> > +            f'if [ "$online" = "{online_cpus}" ]; '
> > +            'then echo RPMI_LINUX_HSM_START_PASS; '
> > +            'else echo RPMI_LINUX_HSM_START_FAIL; fi',
> > +            'RPMI_LINUX_HSM_START_PASS', 'RPMI_LINUX_HSM_START_FAIL')
> > +
> > +    def _validate_hsm_stop(self):
> > +        self._run_marker_command(
> > +            'echo RPMI_LINUX_HSM_STOP_BEGIN; '
> > +            'if [ -w /sys/devices/system/cpu/cpu1/online ]; then '
> > +            'echo 0 > /sys/devices/system/cpu/cpu1/online && '
> > +            '[ "$(cat /sys/devices/system/cpu/online)" = 0 ] && '
> > +            'echo RPMI_LINUX_HSM_STOP_PASS || echo 
> > RPMI_LINUX_HSM_STOP_FAIL; '
> > +            'else echo RPMI_LINUX_HSM_STOP_FAIL; fi',
> > +            'RPMI_LINUX_HSM_STOP_PASS', 'RPMI_LINUX_HSM_STOP_FAIL')
> > +
> > +    def _validate_system_suspend(self):
> > +        exec_command(
> > +            self,
> > +            'echo RPMI_LINUX_SUSPEND_BEGIN; '
> > +            'if grep -qw mem /sys/power/state; then '
> > +            'echo mem > /sys/power/state; '
> > +            'else echo RPMI_LINUX_SUSPEND_FAIL; fi')
> > +        wait_for_console_pattern(self, 'RPMI_LINUX_SUSPEND_BEGIN')
> > +        wait_for_console_pattern(self, 'PM: suspend entry')
> > +        self.vm.event_wait('SUSPEND', 10)
> > +        self.vm.qmp('system_wakeup')
> > +        self.vm.event_wait('WAKEUP', 10)
> > +        wait_for_console_pattern(self, 'PM: suspend exit')
> > +        wait_for_console_pattern(self, self.PROMPT)
> > +        self._run_marker_command(
> > +            'marker=RPMI_LINUX_WAKEUP; echo ${marker}_PASS',
> > +            'RPMI_LINUX_WAKEUP_PASS')
> > +
> > +    def _validate_reset_poweroff(self):
> > +        exec_command(self, 'echo RPMI_LINUX_RESET_POWEROFF_BEGIN; poweroff 
> > -f')
> > +        wait_for_console_pattern(self, 'RPMI_LINUX_RESET_POWEROFF_BEGIN')
> > +        wait_for_console_pattern(self, 'reboot: Power down')
> > +        self.vm.wait()
> > +
> > +    def test_linux_guest_service_enumeration(self):
> > +        self._boot_guest(smp=4)
> > +        self._expect_rpmi_firmware_and_linux()
> > +        self._validate_hsm_boot_start('0-3')
> > +
> > +    def test_linux_guest_hsm_stop(self):
> > +        self._boot_guest(smp=2)
> > +        self._expect_rpmi_firmware_and_linux()
> > +        self._validate_hsm_boot_start('0-1')
> > +        self._validate_hsm_stop()
> > +
> > +    def test_linux_guest_suspend(self):
> > +        self._boot_guest(smp=1)
> > +        self._expect_rpmi_firmware_and_linux()
> > +        self._validate_system_suspend()
> > +
> > +    def test_linux_guest_reset_poweroff(self):
> > +        self._boot_guest(smp=1)
> > +        self._expect_rpmi_firmware_and_linux()
> > +        self._validate_reset_poweroff()
> > +
> > +
> > +if __name__ == '__main__':
> > +    QemuSystemTest.main()
>

Reply via email to