15c2bae21SThomas Huth#!/usr/bin/env python3 25c2bae21SThomas Huth# 35c2bae21SThomas Huth# SPDX-License-Identifier: GPL-2.0-or-later 45c2bae21SThomas Huth# 55c2bae21SThomas Huth# SMMUv3 Functional tests 65c2bae21SThomas Huth# 75c2bae21SThomas Huth# Copyright (c) 2021 Red Hat, Inc. 85c2bae21SThomas Huth# 95c2bae21SThomas Huth# Author: 105c2bae21SThomas Huth# Eric Auger <eric.auger@redhat.com> 115c2bae21SThomas Huth# 125c2bae21SThomas Huth# This work is licensed under the terms of the GNU GPL, version 2 or 135c2bae21SThomas Huth# later. See the COPYING file in the top-level directory. 145c2bae21SThomas Huth 155c2bae21SThomas Huthimport os 165c2bae21SThomas Huthimport time 175c2bae21SThomas Huth 185c2bae21SThomas Huthfrom qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern 195c2bae21SThomas Huthfrom qemu_test import BUILD_DIR 20*9b4c8dd5SPhilippe Mathieu-Daudéfrom qemu.utils import kvm_available, hvf_available 215c2bae21SThomas Huth 225c2bae21SThomas Huth 235c2bae21SThomas Huthclass SMMU(LinuxKernelTest): 245c2bae21SThomas Huth 255c2bae21SThomas Huth default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check ' 265c2bae21SThomas Huth 'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 ' 275c2bae21SThomas Huth 'console=ttyAMA0 rd.rescue') 285c2bae21SThomas Huth IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on' 295c2bae21SThomas Huth kernel_path = None 305c2bae21SThomas Huth initrd_path = None 315c2bae21SThomas Huth kernel_params = None 325c2bae21SThomas Huth 335c2bae21SThomas Huth GUEST_PORT = 8080 345c2bae21SThomas Huth 355c2bae21SThomas Huth def set_up_boot(self, path): 365c2bae21SThomas Huth self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' + 375c2bae21SThomas Huth 'drive=drv0,id=virtio-disk0,bootindex=1,' 385c2bae21SThomas Huth 'werror=stop,rerror=stop' + self.IOMMU_ADDON) 395c2bae21SThomas Huth self.vm.add_args('-drive', 405c2bae21SThomas Huth f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on') 415c2bae21SThomas Huth 425c2bae21SThomas Huth self.vm.add_args('-netdev', 435c2bae21SThomas Huth 'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' % 445c2bae21SThomas Huth self.GUEST_PORT) 455c2bae21SThomas Huth self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON) 465c2bae21SThomas Huth 475c2bae21SThomas Huth def common_vm_setup(self, kernel, initrd, disk): 48*9b4c8dd5SPhilippe Mathieu-Daudé if hvf_available(self.qemu_bin): 49*9b4c8dd5SPhilippe Mathieu-Daudé accel = "hvf" 50*9b4c8dd5SPhilippe Mathieu-Daudé elif kvm_available(self.qemu_bin): 51*9b4c8dd5SPhilippe Mathieu-Daudé accel = "kvm" 52*9b4c8dd5SPhilippe Mathieu-Daudé else: 53*9b4c8dd5SPhilippe Mathieu-Daudé self.skipTest("Neither HVF nor KVM accelerator is available") 54*9b4c8dd5SPhilippe Mathieu-Daudé self.require_accelerator(accel) 555c2bae21SThomas Huth self.require_netdev('user') 565c2bae21SThomas Huth self.set_machine("virt") 575c2bae21SThomas Huth self.vm.add_args('-m', '1G') 58*9b4c8dd5SPhilippe Mathieu-Daudé self.vm.add_args("-accel", accel) 595c2bae21SThomas Huth self.vm.add_args("-cpu", "host") 605c2bae21SThomas Huth self.vm.add_args("-machine", "iommu=smmuv3") 615c2bae21SThomas Huth self.vm.add_args("-d", "guest_errors") 625c2bae21SThomas Huth self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios', 635c2bae21SThomas Huth 'edk2-aarch64-code.fd')) 645c2bae21SThomas Huth self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0') 655c2bae21SThomas Huth self.vm.add_args('-object', 665c2bae21SThomas Huth 'rng-random,id=rng0,filename=/dev/urandom') 675c2bae21SThomas Huth 685c2bae21SThomas Huth self.kernel_path = kernel.fetch() 695c2bae21SThomas Huth self.initrd_path = initrd.fetch() 705c2bae21SThomas Huth self.set_up_boot(disk.fetch()) 715c2bae21SThomas Huth 725c2bae21SThomas Huth def run_and_check(self, filename, hashsum): 735c2bae21SThomas Huth self.vm.add_args('-initrd', self.initrd_path) 745c2bae21SThomas Huth self.vm.add_args('-append', self.kernel_params) 755c2bae21SThomas Huth self.launch_kernel(self.kernel_path, initrd=self.initrd_path, 765c2bae21SThomas Huth wait_for='attach it to a bug report.') 775c2bae21SThomas Huth prompt = '# ' 785c2bae21SThomas Huth # Fedora 33 requires 'return' to be pressed to enter the shell. 795c2bae21SThomas Huth # There seems to be a small race between detecting the previous ':' 805c2bae21SThomas Huth # and sending the newline, so we need to add a small delay here. 815c2bae21SThomas Huth self.wait_for_console_pattern(':') 825c2bae21SThomas Huth time.sleep(0.2) 835c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, '\n', prompt) 845c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline', 855c2bae21SThomas Huth self.kernel_params) 865c2bae21SThomas Huth 875c2bae21SThomas Huth # Checking for SMMU enablement: 885c2bae21SThomas Huth self.log.info("Checking whether SMMU has been enabled...") 895c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu', 905c2bae21SThomas Huth 'arm-smmu-v3') 915c2bae21SThomas Huth self.wait_for_console_pattern(prompt) 925c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 935c2bae21SThomas Huth 'find /sys/kernel/iommu_groups/ -type l', 945c2bae21SThomas Huth 'devices/0000:00:') 955c2bae21SThomas Huth self.wait_for_console_pattern(prompt) 965c2bae21SThomas Huth 975c2bae21SThomas Huth # Copy a file (checked later), umount afterwards to drop disk cache: 985c2bae21SThomas Huth self.log.info("Checking hard disk...") 995c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 1005c2bae21SThomas Huth "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done", 1015c2bae21SThomas Huth "vda2") 1025c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot', 1035c2bae21SThomas Huth 'mounted filesystem') 1045c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'cp /bin/vi /sysroot/root/vi', 1055c2bae21SThomas Huth prompt) 1065c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt) 1075c2bae21SThomas Huth # Switch from initrd to the cloud image filesystem: 1085c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot', 1095c2bae21SThomas Huth prompt) 1105c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 1115c2bae21SThomas Huth ('for d in dev proc sys run ; do ' 1125c2bae21SThomas Huth 'mount -o bind /$d /sysroot/$d ; done'), prompt) 1135c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt) 1145c2bae21SThomas Huth # Check files on the hard disk: 1155c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 1165c2bae21SThomas Huth ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; ' 1175c2bae21SThomas Huth 'else echo "files differ"; fi'), 'file ok') 1185c2bae21SThomas Huth self.wait_for_console_pattern(prompt) 1195c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, f'sha256sum {filename}', 1205c2bae21SThomas Huth hashsum) 1215c2bae21SThomas Huth 1225c2bae21SThomas Huth # Check virtio-net via HTTP: 1235c2bae21SThomas Huth exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt) 1245c2bae21SThomas Huth self.check_http_download(filename, hashsum, self.GUEST_PORT) 1255c2bae21SThomas Huth 1265c2bae21SThomas Huth 1275c2bae21SThomas Huth # 5.3 kernel without RIL # 1285c2bae21SThomas Huth 1295c2bae21SThomas Huth ASSET_KERNEL_F31 = Asset( 1305c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/' 1315c2bae21SThomas Huth 'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'), 1325c2bae21SThomas Huth '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527') 1335c2bae21SThomas Huth 1345c2bae21SThomas Huth ASSET_INITRD_F31 = Asset( 1355c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/' 1365c2bae21SThomas Huth 'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'), 1375c2bae21SThomas Huth '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a') 1385c2bae21SThomas Huth 1395c2bae21SThomas Huth ASSET_DISK_F31 = Asset( 1405c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases' 1415c2bae21SThomas Huth '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'), 1425c2bae21SThomas Huth '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49') 1435c2bae21SThomas Huth 1445c2bae21SThomas Huth F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img' 1455c2bae21SThomas Huth F31_HSUM = '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9' 1465c2bae21SThomas Huth 1475c2bae21SThomas Huth def test_smmu_noril(self): 1485c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31, 1495c2bae21SThomas Huth self.ASSET_DISK_F31) 1505c2bae21SThomas Huth self.kernel_params = self.default_kernel_params 1515c2bae21SThomas Huth self.run_and_check(self.F31_FILENAME, self.F31_HSUM) 1525c2bae21SThomas Huth 1535c2bae21SThomas Huth def test_smmu_noril_passthrough(self): 1545c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31, 1555c2bae21SThomas Huth self.ASSET_DISK_F31) 1565c2bae21SThomas Huth self.kernel_params = (self.default_kernel_params + 1575c2bae21SThomas Huth ' iommu.passthrough=on') 1585c2bae21SThomas Huth self.run_and_check(self.F31_FILENAME, self.F31_HSUM) 1595c2bae21SThomas Huth 1605c2bae21SThomas Huth def test_smmu_noril_nostrict(self): 1615c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31, 1625c2bae21SThomas Huth self.ASSET_DISK_F31) 1635c2bae21SThomas Huth self.kernel_params = (self.default_kernel_params + 1645c2bae21SThomas Huth ' iommu.strict=0') 1655c2bae21SThomas Huth self.run_and_check(self.F31_FILENAME, self.F31_HSUM) 1665c2bae21SThomas Huth 1675c2bae21SThomas Huth 1685c2bae21SThomas Huth # 5.8 kernel featuring range invalidation 1695c2bae21SThomas Huth # >= v5.7 kernel 1705c2bae21SThomas Huth 1715c2bae21SThomas Huth ASSET_KERNEL_F33 = Asset( 1725c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/' 1735c2bae21SThomas Huth 'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'), 1745c2bae21SThomas Huth 'd8b1e6f7241f339d8e7609c456cf0461ffa4583ed07e0b55c7d1d8a0c154aa89') 1755c2bae21SThomas Huth 1765c2bae21SThomas Huth ASSET_INITRD_F33 = Asset( 1775c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/' 1785c2bae21SThomas Huth 'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'), 1795c2bae21SThomas Huth '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df') 1805c2bae21SThomas Huth 1815c2bae21SThomas Huth ASSET_DISK_F33 = Asset( 1825c2bae21SThomas Huth ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases' 1835c2bae21SThomas Huth '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'), 1845c2bae21SThomas Huth 'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b') 1855c2bae21SThomas Huth 1865c2bae21SThomas Huth F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img' 1875c2bae21SThomas Huth F33_HSUM = '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9' 1885c2bae21SThomas Huth 1895c2bae21SThomas Huth def test_smmu_ril(self): 1905c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33, 1915c2bae21SThomas Huth self.ASSET_DISK_F33) 1925c2bae21SThomas Huth self.kernel_params = self.default_kernel_params 1935c2bae21SThomas Huth self.run_and_check(self.F33_FILENAME, self.F33_HSUM) 1945c2bae21SThomas Huth 1955c2bae21SThomas Huth def test_smmu_ril_passthrough(self): 1965c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33, 1975c2bae21SThomas Huth self.ASSET_DISK_F33) 1985c2bae21SThomas Huth self.kernel_params = (self.default_kernel_params + 1995c2bae21SThomas Huth ' iommu.passthrough=on') 2005c2bae21SThomas Huth self.run_and_check(self.F33_FILENAME, self.F33_HSUM) 2015c2bae21SThomas Huth 2025c2bae21SThomas Huth def test_smmu_ril_nostrict(self): 2035c2bae21SThomas Huth self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33, 2045c2bae21SThomas Huth self.ASSET_DISK_F33) 2055c2bae21SThomas Huth self.kernel_params = (self.default_kernel_params + 2065c2bae21SThomas Huth ' iommu.strict=0') 2075c2bae21SThomas Huth self.run_and_check(self.F33_FILENAME, self.F33_HSUM) 2085c2bae21SThomas Huth 2095c2bae21SThomas Huth 2105c2bae21SThomas Huthif __name__ == '__main__': 2115c2bae21SThomas Huth LinuxKernelTest.main() 212