Hi Thomas,

On 3/11/25 11:49 AM, Thomas Huth wrote:
> This test was using cloudinit and a "dnf install" command in the guest
> to exercise the NIC with SMMU enabled. Since we don't have the cloudinit
> stuff in the functional framework and we should not rely on having access
> to external networks (once our ASSETs have been cached), we rather boot
> into the initrd first, manually mount the root disk and then use the
> check_http_download() function from the functional framework here instead
> for testing whether the network works as expected.
>
> Unfortunately, there seems to be a small race when using the files
> from Fedora 33: To enter the initrd shell, we have to send a "return"
> once. But it does not seem to work if we send it too early. Using a
> sleep(0.2) makes it work reliably for me, but to make it even more
> unlikely to trigger this situation, let's better limit the Fedora 33
> tests to only run with KVM.
>
> Finally, while we're at it, we also add some lines for testing writes
> to the hard disk, as we already do it in the test_intel_iommu test.

for your info it does not apply anymore on mainline after latest appied
functional test additions.
>
> Signed-off-by: Thomas Huth <th...@redhat.com>
> ---
>  MAINTAINERS                                   |   2 +-
>  tests/functional/meson.build                  |   2 +
>  .../test_aarch64_smmu.py}                     | 243 +++++++++++-------
>  3 files changed, 159 insertions(+), 88 deletions(-)
>  rename tests/{avocado/smmu.py => functional/test_aarch64_smmu.py} (17%)
>  mode change 100644 => 100755
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 90e48b26715..211e70c6942 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -218,7 +218,7 @@ L: qemu-...@nongnu.org
>  S: Maintained
>  F: hw/arm/smmu*
>  F: include/hw/arm/smmu*
> -F: tests/avocado/smmu.py
> +F: tests/functional/test_aarch64_smmu.py
>  
>  AVR TCG CPUs
>  M: Michael Rolnik <mrol...@gmail.com>
> diff --git a/tests/functional/meson.build b/tests/functional/meson.build
> index 43a34c6447e..e8bf0e4a6bc 100644
> --- a/tests/functional/meson.build
> +++ b/tests/functional/meson.build
> @@ -18,6 +18,7 @@ test_timeouts = {
>    'aarch64_rme_sbsaref' : 1200,
>    'aarch64_sbsaref_alpine' : 1200,
>    'aarch64_sbsaref_freebsd' : 720,
> +  'aarch64_smmu' : 720,
>    'aarch64_tuxrun' : 240,
>    'aarch64_virt' : 720,
>    'acpi_bits' : 420,
> @@ -84,6 +85,7 @@ tests_aarch64_system_thorough = [
>    'aarch64_sbsaref',
>    'aarch64_sbsaref_alpine',
>    'aarch64_sbsaref_freebsd',
> +  'aarch64_smmu',
>    'aarch64_tcg_plugins',
>    'aarch64_tuxrun',
>    'aarch64_virt',
> diff --git a/tests/avocado/smmu.py b/tests/functional/test_aarch64_smmu.py
> old mode 100644
> new mode 100755
> similarity index 17%
> rename from tests/avocado/smmu.py
> rename to tests/functional/test_aarch64_smmu.py
> index 83fd79e922e..bba8599401c
> --- a/tests/avocado/smmu.py
> +++ b/tests/functional/test_aarch64_smmu.py
> @@ -1,3 +1,5 @@
> +#!/usr/bin/env python3
> +#
>  # SMMUv3 Functional tests
>  #
>  # Copyright (c) 2021 Red Hat, Inc.
> @@ -7,44 +9,48 @@
>  #
>  # This work is licensed under the terms of the GNU GPL, version 2 or
>  # later.  See the COPYING file in the top-level directory.
> +
>  import os
> +import time
> +
> +from qemu_test import LinuxKernelTest, Asset, 
> exec_command_and_wait_for_pattern
> +from qemu_test import BUILD_DIR
> +from qemu.utils import kvm_available
>  
> -from avocado import skipUnless
> -from avocado_qemu import BUILD_DIR
> -from avocado_qemu.linuxtest import LinuxTest
> -
> -@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
> -class SMMU(LinuxTest):
> -    """
> -    :avocado: tags=accel:kvm
> -    :avocado: tags=cpu:host
> -    :avocado: tags=arch:aarch64
> -    :avocado: tags=machine:virt
> -    :avocado: tags=distro:fedora
> -    :avocado: tags=smmu
> -    :avocado: tags=flaky
> -    """
>  
> +class SMMU(LinuxKernelTest):
> +
> +    default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check '
> +                             'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 '
> +                             'console=ttyAMA0 rd.rescue')
>      IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
>      kernel_path = None
>      initrd_path = None
>      kernel_params = None
>  
> -    def set_up_boot(self):
> -        path = self.download_boot()
> +    GUEST_PORT = 8080
> +
> +    def set_up_boot(self, path):
>          self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
>                           'drive=drv0,id=virtio-disk0,bootindex=1,'
>                           'werror=stop,rerror=stop' + self.IOMMU_ADDON)
>          self.vm.add_args('-drive',
> -                         'file=%s,if=none,cache=writethrough,id=drv0' % path)
> -
> -    def setUp(self):
> -        super(SMMU, self).setUp(None, 'virtio-net-pci' + self.IOMMU_ADDON)
> -
> -    def common_vm_setup(self, custom_kernel=False):
> -        self.require_accelerator("kvm")
> -        self.vm.add_args("-accel", "kvm")
> -        self.vm.add_args("-cpu", "host")
> +                
> f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on')
> +
> +        self.vm.add_args('-netdev',
> +                         'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
> +                         self.GUEST_PORT)
> +        self.vm.add_args('-device', 'virtio-net,netdev=n1' + 
> self.IOMMU_ADDON)
> +
> +    def common_vm_setup(self, kernel, initrd, disk):
> +        self.set_machine("virt")
> +        self.require_netdev('user')
> +        if kvm_available(qemu_bin=self.qemu_bin):
> +            self.vm.add_args("-accel", "kvm")
> +            self.vm.add_args("-cpu", "host")
> +        else:
> +            self.vm.add_args("-cpu", "cortex-a57")
> +        self.vm.add_args('-m', '1G')
>          self.vm.add_args("-machine", "iommu=smmuv3")
>          self.vm.add_args("-d", "guest_errors")
>          self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
> @@ -53,87 +59,150 @@ def common_vm_setup(self, custom_kernel=False):
>          self.vm.add_args('-object',
>                           'rng-random,id=rng0,filename=/dev/urandom')
>  
> -        if custom_kernel is False:
> -            return
> +        self.kernel_path = kernel.fetch()
> +        self.initrd_path = initrd.fetch()
> +        self.set_up_boot(disk.fetch())
> +
> +    def run_and_check(self, filename, hashsum):
> +        self.vm.add_args('-initrd', self.initrd_path)
> +        self.vm.add_args('-append', self.kernel_params)
> +        self.launch_kernel(self.kernel_path, initrd=self.initrd_path,
> +                           wait_for='attach it to a bug report.')
> +        prompt = '# '
> +        # Fedora 33 requires 'return' to be pressed to enter the shell.
> +        # There seems to be a small race between detecting the previous ':'
> +        # and sending the newline, so we need to add a small delay here.
> +        self.wait_for_console_pattern(':')
> +        time.sleep(0.2)
> +        exec_command_and_wait_for_pattern(self, '\n', prompt)
> +        exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
> +                                          self.kernel_params)
> +
> +        # Checking for SMMU enablement:
> +        self.log.info("Checking whether SMMU has been enabled...")
> +        exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu',
> +                                          'arm-smmu-v3')
> +        self.wait_for_console_pattern(prompt)
> +        exec_command_and_wait_for_pattern(self,
> +                                    'find /sys/kernel/iommu_groups/ -type l',
> +                                    'devices/0000:00:')
> +        self.wait_for_console_pattern(prompt)
> +
> +        # Copy a file (checked later), umount afterwards to drop disk cache:
> +        self.log.info("Checking hard disk...")
> +        exec_command_and_wait_for_pattern(self,
> +                        "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done",
> +                        "vda2")
> +        exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
> +                                          'mounted filesystem')
> +        exec_command_and_wait_for_pattern(self, 'cp /bin/vi 
> /sysroot/root/vi',
> +                                          prompt)
> +        exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
> +        # Switch from initrd to the cloud image filesystem:
> +        exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
> +                                          prompt)
> +        exec_command_and_wait_for_pattern(self,
> +                ('for d in dev proc sys run ; do '
> +                 'mount -o bind /$d /sysroot/$d ; done'), prompt)
> +        exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
> +        # Check files on the hard disk:
> +        exec_command_and_wait_for_pattern(self,
> +            ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; '
> +             'else echo "files differ"; fi'), 'file ok')
> +        self.wait_for_console_pattern(prompt)
> +        exec_command_and_wait_for_pattern(self, f'sha256sum {filename}',
> +                                          hashsum)
> +
> +        # Check virtio-net via HTTP:
> +        exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
> +        self.check_http_download(filename, hashsum, self.GUEST_PORT)
>  
> -        kernel_url = self.distro.pxeboot_url + 'vmlinuz'
> -        initrd_url = self.distro.pxeboot_url + 'initrd.img'
> -        self.kernel_path = self.fetch_asset(kernel_url)
> -        self.initrd_path = self.fetch_asset(initrd_url)
>  
> -    def run_and_check(self):
> -        if self.kernel_path:
> -            self.vm.add_args('-kernel', self.kernel_path,
> -                             '-append', self.kernel_params,
> -                             '-initrd', self.initrd_path)
> -        self.launch_and_wait()
> -        self.ssh_command('cat /proc/cmdline')
> -        self.ssh_command('dnf -y install numactl-devel')
> +    # 5.3 kernel without RIL #
>  
> +    ASSET_KERNEL_F31 = Asset(
> +        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
> +         'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'),
> +        '413c7f95e7f40cfa3e73290ffae855c88fae54cccc46123a4b4ed2db7d5c2120')
the hash seems wrong for the vmlinuz. I get
Exception: Hash of
https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/31/Server/aarch64/os/images/pxeboot/vmlinuz
does not match
413c7f95e7f40cfa3e73290ffae855c88fae54cccc46123a4b4ed2db7d5c2120

>  
> -    # 5.3 kernel without RIL #
> +    ASSET_INITRD_F31 = Asset(
> +        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
> +         'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'),
> +        '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a')
> +
> +    ASSET_DISK_F31 = Asset(
> +        
> ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
> +         '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'),
> +        '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49')
> +
> +    F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img'
> +    F31_HSUM = 
> '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9'
>  
>      def test_smmu_noril(self):
> -        """
> -        :avocado: tags=smmu_noril
> -        :avocado: tags=smmu_noril_tests
> -        :avocado: tags=distro_version:31
> -        """
> -        self.common_vm_setup()
> -        self.run_and_check()
> +        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
> +                             self.ASSET_DISK_F31)
> +        self.kernel_params = self.default_kernel_params
> +        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
>  
>      def test_smmu_noril_passthrough(self):
> -        """
> -        :avocado: tags=smmu_noril_passthrough
> -        :avocado: tags=smmu_noril_tests
> -        :avocado: tags=distro_version:31
> -        """
> -        self.common_vm_setup(True)
> -        self.kernel_params = (self.distro.default_kernel_params +
> +        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
> +                             self.ASSET_DISK_F31)
> +        self.kernel_params = (self.default_kernel_params +
>                                ' iommu.passthrough=on')
> -        self.run_and_check()
> +        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
>  
>      def test_smmu_noril_nostrict(self):
> -        """
> -        :avocado: tags=smmu_noril_nostrict
> -        :avocado: tags=smmu_noril_tests
> -        :avocado: tags=distro_version:31
> -        """
> -        self.common_vm_setup(True)
> -        self.kernel_params = (self.distro.default_kernel_params +
> +        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
> +                             self.ASSET_DISK_F31)
> +        self.kernel_params = (self.default_kernel_params +
>                                ' iommu.strict=0')
> -        self.run_and_check()
> +        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
> +
>  
>      # 5.8 kernel featuring range invalidation
>      # >= v5.7 kernel
>  
> +    ASSET_KERNEL_F33 = Asset(
> +        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
> +         'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'),
> +        '0ef9e34f80b49fa2ac098899b27075e95c11d5b646f6ca4df2e89237a40f9e4f')
same here I get
Exception: Hash of
https://archives.fedoraproject.org/pub/archive/fedora/linux/releases/33/Server/aarch64/os/images/pxeboot/vmlinuz
does not match
0ef9e34f80b49fa2ac098899b27075e95c11d5b646f6ca4df2e89237a40f9e4f

> +
> +    ASSET_INITRD_F33 = Asset(
> +        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
> +         'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'),
> +        '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df')
> +
> +    ASSET_DISK_F33 = Asset(
> +        
> ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
> +         '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'),
> +        'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b')
> +
> +    F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img'
> +    F33_HSUM = 
> '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9'
> +
>      def test_smmu_ril(self):
> -        """
> -        :avocado: tags=smmu_ril
> -        :avocado: tags=smmu_ril_tests
> -        :avocado: tags=distro_version:33
> -        """
> -        self.common_vm_setup()
> -        self.run_and_check()
> +        self.require_accelerator("kvm")
> +        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
> +                             self.ASSET_DISK_F33)
> +        self.kernel_params = self.default_kernel_params
> +        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
>  
>      def test_smmu_ril_passthrough(self):
> -        """
> -        :avocado: tags=smmu_ril_passthrough
> -        :avocado: tags=smmu_ril_tests
> -        :avocado: tags=distro_version:33
> -        """
> -        self.common_vm_setup(True)
> -        self.kernel_params = (self.distro.default_kernel_params +
> +        self.require_accelerator("kvm")
> +        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
> +                             self.ASSET_DISK_F33)
> +        self.kernel_params = (self.default_kernel_params +
>                                ' iommu.passthrough=on')
> -        self.run_and_check()
> +        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
>  
>      def test_smmu_ril_nostrict(self):
> -        """
> -        :avocado: tags=smmu_ril_nostrict
> -        :avocado: tags=smmu_ril_tests
> -        :avocado: tags=distro_version:33
> -        """
> -        self.common_vm_setup(True)
> -        self.kernel_params = (self.distro.default_kernel_params +
> +        self.require_accelerator("kvm")
> +        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
> +                             self.ASSET_DISK_F33)
> +        self.kernel_params = (self.default_kernel_params +
>                                ' iommu.strict=0')
> -        self.run_and_check()
> +        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
> +
> +
> +if __name__ == '__main__':
> +    LinuxKernelTest.main()
Thanks

Eric


Reply via email to