xref: /qemu/tests/functional/test_aarch64_smmu.py (revision 55f5bf716a65f67663d0769bcb8c017764b3e53a)
1*5c2bae21SThomas Huth#!/usr/bin/env python3
2*5c2bae21SThomas Huth#
3*5c2bae21SThomas Huth# SPDX-License-Identifier: GPL-2.0-or-later
4*5c2bae21SThomas Huth#
5*5c2bae21SThomas Huth# SMMUv3 Functional tests
6*5c2bae21SThomas Huth#
7*5c2bae21SThomas Huth# Copyright (c) 2021 Red Hat, Inc.
8*5c2bae21SThomas Huth#
9*5c2bae21SThomas Huth# Author:
10*5c2bae21SThomas Huth#  Eric Auger <eric.auger@redhat.com>
11*5c2bae21SThomas Huth#
12*5c2bae21SThomas Huth# This work is licensed under the terms of the GNU GPL, version 2 or
13*5c2bae21SThomas Huth# later.  See the COPYING file in the top-level directory.
14*5c2bae21SThomas Huth
15*5c2bae21SThomas Huthimport os
16*5c2bae21SThomas Huthimport time
17*5c2bae21SThomas Huth
18*5c2bae21SThomas Huthfrom qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
19*5c2bae21SThomas Huthfrom qemu_test import BUILD_DIR
20*5c2bae21SThomas Huthfrom qemu.utils import kvm_available
21*5c2bae21SThomas Huth
22*5c2bae21SThomas Huth
23*5c2bae21SThomas Huthclass SMMU(LinuxKernelTest):
24*5c2bae21SThomas Huth
25*5c2bae21SThomas Huth    default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check '
26*5c2bae21SThomas Huth                             'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 '
27*5c2bae21SThomas Huth                             'console=ttyAMA0 rd.rescue')
28*5c2bae21SThomas Huth    IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
29*5c2bae21SThomas Huth    kernel_path = None
30*5c2bae21SThomas Huth    initrd_path = None
31*5c2bae21SThomas Huth    kernel_params = None
32*5c2bae21SThomas Huth
33*5c2bae21SThomas Huth    GUEST_PORT = 8080
34*5c2bae21SThomas Huth
35*5c2bae21SThomas Huth    def set_up_boot(self, path):
36*5c2bae21SThomas Huth        self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
37*5c2bae21SThomas Huth                         'drive=drv0,id=virtio-disk0,bootindex=1,'
38*5c2bae21SThomas Huth                         'werror=stop,rerror=stop' + self.IOMMU_ADDON)
39*5c2bae21SThomas Huth        self.vm.add_args('-drive',
40*5c2bae21SThomas Huth                f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on')
41*5c2bae21SThomas Huth
42*5c2bae21SThomas Huth        self.vm.add_args('-netdev',
43*5c2bae21SThomas Huth                         'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
44*5c2bae21SThomas Huth                         self.GUEST_PORT)
45*5c2bae21SThomas Huth        self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
46*5c2bae21SThomas Huth
47*5c2bae21SThomas Huth    def common_vm_setup(self, kernel, initrd, disk):
48*5c2bae21SThomas Huth        self.require_accelerator("kvm")
49*5c2bae21SThomas Huth        self.require_netdev('user')
50*5c2bae21SThomas Huth        self.set_machine("virt")
51*5c2bae21SThomas Huth        self.vm.add_args('-m', '1G')
52*5c2bae21SThomas Huth        self.vm.add_args("-accel", "kvm")
53*5c2bae21SThomas Huth        self.vm.add_args("-cpu", "host")
54*5c2bae21SThomas Huth        self.vm.add_args("-machine", "iommu=smmuv3")
55*5c2bae21SThomas Huth        self.vm.add_args("-d", "guest_errors")
56*5c2bae21SThomas Huth        self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
57*5c2bae21SThomas Huth                         'edk2-aarch64-code.fd'))
58*5c2bae21SThomas Huth        self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
59*5c2bae21SThomas Huth        self.vm.add_args('-object',
60*5c2bae21SThomas Huth                         'rng-random,id=rng0,filename=/dev/urandom')
61*5c2bae21SThomas Huth
62*5c2bae21SThomas Huth        self.kernel_path = kernel.fetch()
63*5c2bae21SThomas Huth        self.initrd_path = initrd.fetch()
64*5c2bae21SThomas Huth        self.set_up_boot(disk.fetch())
65*5c2bae21SThomas Huth
66*5c2bae21SThomas Huth    def run_and_check(self, filename, hashsum):
67*5c2bae21SThomas Huth        self.vm.add_args('-initrd', self.initrd_path)
68*5c2bae21SThomas Huth        self.vm.add_args('-append', self.kernel_params)
69*5c2bae21SThomas Huth        self.launch_kernel(self.kernel_path, initrd=self.initrd_path,
70*5c2bae21SThomas Huth                           wait_for='attach it to a bug report.')
71*5c2bae21SThomas Huth        prompt = '# '
72*5c2bae21SThomas Huth        # Fedora 33 requires 'return' to be pressed to enter the shell.
73*5c2bae21SThomas Huth        # There seems to be a small race between detecting the previous ':'
74*5c2bae21SThomas Huth        # and sending the newline, so we need to add a small delay here.
75*5c2bae21SThomas Huth        self.wait_for_console_pattern(':')
76*5c2bae21SThomas Huth        time.sleep(0.2)
77*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, '\n', prompt)
78*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
79*5c2bae21SThomas Huth                                          self.kernel_params)
80*5c2bae21SThomas Huth
81*5c2bae21SThomas Huth        # Checking for SMMU enablement:
82*5c2bae21SThomas Huth        self.log.info("Checking whether SMMU has been enabled...")
83*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu',
84*5c2bae21SThomas Huth                                          'arm-smmu-v3')
85*5c2bae21SThomas Huth        self.wait_for_console_pattern(prompt)
86*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self,
87*5c2bae21SThomas Huth                                    'find /sys/kernel/iommu_groups/ -type l',
88*5c2bae21SThomas Huth                                    'devices/0000:00:')
89*5c2bae21SThomas Huth        self.wait_for_console_pattern(prompt)
90*5c2bae21SThomas Huth
91*5c2bae21SThomas Huth        # Copy a file (checked later), umount afterwards to drop disk cache:
92*5c2bae21SThomas Huth        self.log.info("Checking hard disk...")
93*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self,
94*5c2bae21SThomas Huth                        "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done",
95*5c2bae21SThomas Huth                        "vda2")
96*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
97*5c2bae21SThomas Huth                                          'mounted filesystem')
98*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'cp /bin/vi /sysroot/root/vi',
99*5c2bae21SThomas Huth                                          prompt)
100*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
101*5c2bae21SThomas Huth        # Switch from initrd to the cloud image filesystem:
102*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
103*5c2bae21SThomas Huth                                          prompt)
104*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self,
105*5c2bae21SThomas Huth                ('for d in dev proc sys run ; do '
106*5c2bae21SThomas Huth                 'mount -o bind /$d /sysroot/$d ; done'), prompt)
107*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
108*5c2bae21SThomas Huth        # Check files on the hard disk:
109*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self,
110*5c2bae21SThomas Huth            ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; '
111*5c2bae21SThomas Huth             'else echo "files differ"; fi'), 'file ok')
112*5c2bae21SThomas Huth        self.wait_for_console_pattern(prompt)
113*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, f'sha256sum {filename}',
114*5c2bae21SThomas Huth                                          hashsum)
115*5c2bae21SThomas Huth
116*5c2bae21SThomas Huth        # Check virtio-net via HTTP:
117*5c2bae21SThomas Huth        exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
118*5c2bae21SThomas Huth        self.check_http_download(filename, hashsum, self.GUEST_PORT)
119*5c2bae21SThomas Huth
120*5c2bae21SThomas Huth
121*5c2bae21SThomas Huth    # 5.3 kernel without RIL #
122*5c2bae21SThomas Huth
123*5c2bae21SThomas Huth    ASSET_KERNEL_F31 = Asset(
124*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
125*5c2bae21SThomas Huth         'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'),
126*5c2bae21SThomas Huth        '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
127*5c2bae21SThomas Huth
128*5c2bae21SThomas Huth    ASSET_INITRD_F31 = Asset(
129*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
130*5c2bae21SThomas Huth         'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'),
131*5c2bae21SThomas Huth        '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a')
132*5c2bae21SThomas Huth
133*5c2bae21SThomas Huth    ASSET_DISK_F31 = Asset(
134*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
135*5c2bae21SThomas Huth         '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'),
136*5c2bae21SThomas Huth        '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49')
137*5c2bae21SThomas Huth
138*5c2bae21SThomas Huth    F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img'
139*5c2bae21SThomas Huth    F31_HSUM = '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9'
140*5c2bae21SThomas Huth
141*5c2bae21SThomas Huth    def test_smmu_noril(self):
142*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
143*5c2bae21SThomas Huth                             self.ASSET_DISK_F31)
144*5c2bae21SThomas Huth        self.kernel_params = self.default_kernel_params
145*5c2bae21SThomas Huth        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
146*5c2bae21SThomas Huth
147*5c2bae21SThomas Huth    def test_smmu_noril_passthrough(self):
148*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
149*5c2bae21SThomas Huth                             self.ASSET_DISK_F31)
150*5c2bae21SThomas Huth        self.kernel_params = (self.default_kernel_params +
151*5c2bae21SThomas Huth                              ' iommu.passthrough=on')
152*5c2bae21SThomas Huth        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
153*5c2bae21SThomas Huth
154*5c2bae21SThomas Huth    def test_smmu_noril_nostrict(self):
155*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
156*5c2bae21SThomas Huth                             self.ASSET_DISK_F31)
157*5c2bae21SThomas Huth        self.kernel_params = (self.default_kernel_params +
158*5c2bae21SThomas Huth                              ' iommu.strict=0')
159*5c2bae21SThomas Huth        self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
160*5c2bae21SThomas Huth
161*5c2bae21SThomas Huth
162*5c2bae21SThomas Huth    # 5.8 kernel featuring range invalidation
163*5c2bae21SThomas Huth    # >= v5.7 kernel
164*5c2bae21SThomas Huth
165*5c2bae21SThomas Huth    ASSET_KERNEL_F33 = Asset(
166*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
167*5c2bae21SThomas Huth         'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'),
168*5c2bae21SThomas Huth        'd8b1e6f7241f339d8e7609c456cf0461ffa4583ed07e0b55c7d1d8a0c154aa89')
169*5c2bae21SThomas Huth
170*5c2bae21SThomas Huth    ASSET_INITRD_F33 = Asset(
171*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
172*5c2bae21SThomas Huth         'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'),
173*5c2bae21SThomas Huth        '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df')
174*5c2bae21SThomas Huth
175*5c2bae21SThomas Huth    ASSET_DISK_F33 = Asset(
176*5c2bae21SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
177*5c2bae21SThomas Huth         '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'),
178*5c2bae21SThomas Huth        'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b')
179*5c2bae21SThomas Huth
180*5c2bae21SThomas Huth    F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img'
181*5c2bae21SThomas Huth    F33_HSUM = '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9'
182*5c2bae21SThomas Huth
183*5c2bae21SThomas Huth    def test_smmu_ril(self):
184*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
185*5c2bae21SThomas Huth                             self.ASSET_DISK_F33)
186*5c2bae21SThomas Huth        self.kernel_params = self.default_kernel_params
187*5c2bae21SThomas Huth        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
188*5c2bae21SThomas Huth
189*5c2bae21SThomas Huth    def test_smmu_ril_passthrough(self):
190*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
191*5c2bae21SThomas Huth                             self.ASSET_DISK_F33)
192*5c2bae21SThomas Huth        self.kernel_params = (self.default_kernel_params +
193*5c2bae21SThomas Huth                              ' iommu.passthrough=on')
194*5c2bae21SThomas Huth        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
195*5c2bae21SThomas Huth
196*5c2bae21SThomas Huth    def test_smmu_ril_nostrict(self):
197*5c2bae21SThomas Huth        self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
198*5c2bae21SThomas Huth                             self.ASSET_DISK_F33)
199*5c2bae21SThomas Huth        self.kernel_params = (self.default_kernel_params +
200*5c2bae21SThomas Huth                              ' iommu.strict=0')
201*5c2bae21SThomas Huth        self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
202*5c2bae21SThomas Huth
203*5c2bae21SThomas Huth
204*5c2bae21SThomas Huthif __name__ == '__main__':
205*5c2bae21SThomas Huth    LinuxKernelTest.main()
206