xref: /qemu/tests/functional/test_intel_iommu.py (revision e88a579392f74aa7658299f29dc43aca199e4533)
1270d4a51SThomas Huth#!/usr/bin/env python3
2270d4a51SThomas Huth#
3270d4a51SThomas Huth# INTEL_IOMMU Functional tests
4270d4a51SThomas Huth#
5270d4a51SThomas Huth# Copyright (c) 2021 Red Hat, Inc.
6270d4a51SThomas Huth#
7270d4a51SThomas Huth# Author:
8270d4a51SThomas Huth#  Eric Auger <eric.auger@redhat.com>
9270d4a51SThomas Huth#
10270d4a51SThomas Huth# This work is licensed under the terms of the GNU GPL, version 2 or
11270d4a51SThomas Huth# later.  See the COPYING file in the top-level directory.
12270d4a51SThomas Huth
13270d4a51SThomas Huthfrom qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
14270d4a51SThomas Huth
15270d4a51SThomas Huth
16270d4a51SThomas Huthclass IntelIOMMU(LinuxKernelTest):
17270d4a51SThomas Huth
18270d4a51SThomas Huth    ASSET_KERNEL = Asset(
19270d4a51SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
20270d4a51SThomas Huth         '/31/Server/x86_64/os/images/pxeboot/vmlinuz'),
21270d4a51SThomas Huth        'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
22270d4a51SThomas Huth
23270d4a51SThomas Huth    ASSET_INITRD = Asset(
24270d4a51SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
25270d4a51SThomas Huth         '/31/Server/x86_64/os/images/pxeboot/initrd.img'),
26270d4a51SThomas Huth        '277cd6c7adf77c7e63d73bbb2cded8ef9e2d3a2f100000e92ff1f8396513cd8b')
27270d4a51SThomas Huth
28270d4a51SThomas Huth    ASSET_DISKIMAGE = Asset(
29270d4a51SThomas Huth        ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
30270d4a51SThomas Huth         '/31/Cloud/x86_64/images/Fedora-Cloud-Base-31-1.9.x86_64.qcow2'),
31270d4a51SThomas Huth        'e3c1b309d9203604922d6e255c2c5d098a309c2d46215d8fc026954f3c5c27a0')
32270d4a51SThomas Huth
33270d4a51SThomas Huth    DEFAULT_KERNEL_PARAMS = ('root=/dev/vda1 console=ttyS0 net.ifnames=0 '
34270d4a51SThomas Huth                             'quiet rd.rescue ')
35270d4a51SThomas Huth    GUEST_PORT = 8080
36270d4a51SThomas Huth    IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
37270d4a51SThomas Huth    kernel_path = None
38270d4a51SThomas Huth    initrd_path = None
39270d4a51SThomas Huth    kernel_params = None
40270d4a51SThomas Huth
41270d4a51SThomas Huth    def add_common_args(self, path):
42270d4a51SThomas Huth        self.vm.add_args('-drive', f'file={path},if=none,id=drv0,snapshot=on')
43270d4a51SThomas Huth        self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
44270d4a51SThomas Huth                         'drive=drv0,id=virtio-disk0,bootindex=1,'
45270d4a51SThomas Huth                         'werror=stop,rerror=stop' + self.IOMMU_ADDON)
46270d4a51SThomas Huth        self.vm.add_args('-device', 'virtio-gpu-pci' + self.IOMMU_ADDON)
47270d4a51SThomas Huth
48270d4a51SThomas Huth        self.vm.add_args('-netdev',
49270d4a51SThomas Huth                         'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
50270d4a51SThomas Huth                         self.GUEST_PORT)
51270d4a51SThomas Huth        self.vm.add_args('-device',
52270d4a51SThomas Huth                         'virtio-net-pci,netdev=n1' + self.IOMMU_ADDON)
53270d4a51SThomas Huth
54270d4a51SThomas Huth        self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
55270d4a51SThomas Huth        self.vm.add_args('-object',
56270d4a51SThomas Huth                         'rng-random,id=rng0,filename=/dev/urandom')
57270d4a51SThomas Huth        self.vm.add_args("-m", "1G")
58270d4a51SThomas Huth        self.vm.add_args("-accel", "kvm")
59270d4a51SThomas Huth
60270d4a51SThomas Huth    def common_vm_setup(self):
61270d4a51SThomas Huth        self.set_machine('q35')
62270d4a51SThomas Huth        self.require_accelerator("kvm")
63270d4a51SThomas Huth        self.require_netdev('user')
64270d4a51SThomas Huth
65270d4a51SThomas Huth        self.kernel_path = self.ASSET_KERNEL.fetch()
66270d4a51SThomas Huth        self.initrd_path = self.ASSET_INITRD.fetch()
67270d4a51SThomas Huth        image_path = self.ASSET_DISKIMAGE.fetch()
68270d4a51SThomas Huth        self.add_common_args(image_path)
69270d4a51SThomas Huth        self.kernel_params = self.DEFAULT_KERNEL_PARAMS
70270d4a51SThomas Huth
71270d4a51SThomas Huth    def run_and_check(self):
72270d4a51SThomas Huth        if self.kernel_path:
73270d4a51SThomas Huth            self.vm.add_args('-kernel', self.kernel_path,
74270d4a51SThomas Huth                             '-append', self.kernel_params,
75270d4a51SThomas Huth                             '-initrd', self.initrd_path)
76270d4a51SThomas Huth        self.vm.set_console()
77270d4a51SThomas Huth        self.vm.launch()
78270d4a51SThomas Huth        self.wait_for_console_pattern('Entering emergency mode.')
79270d4a51SThomas Huth        prompt = '# '
80270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
81270d4a51SThomas Huth
82270d4a51SThomas Huth        # Copy a file (checked later), umount afterwards to drop disk cache:
83270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'mount /dev/vda1 /sysroot',
84270d4a51SThomas Huth                                          prompt)
85270d4a51SThomas Huth        filename = '/boot/initramfs-5.3.7-301.fc31.x86_64.img'
86270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, (f'cp /sysroot{filename}'
87270d4a51SThomas Huth                                                 ' /sysroot/root/data'),
88270d4a51SThomas Huth                                          prompt)
89270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
90270d4a51SThomas Huth
91270d4a51SThomas Huth        # Switch from initrd to the cloud image filesystem:
92270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'mount /dev/vda1 /sysroot',
93270d4a51SThomas Huth                                          prompt)
94270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self,
95270d4a51SThomas Huth                ('for d in dev proc sys run ; do '
96270d4a51SThomas Huth                 'mount -o bind /$d /sysroot/$d ; done'), prompt)
97270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
98270d4a51SThomas Huth
99270d4a51SThomas Huth        # Checking for IOMMU enablement:
100270d4a51SThomas Huth        self.log.info("Checking whether IOMMU has been enabled...")
101270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
102270d4a51SThomas Huth                                          'intel_iommu=on')
103270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
104270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'dmesg | grep DMAR:',
105270d4a51SThomas Huth                                          'IOMMU enabled')
106270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
107270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self,
108270d4a51SThomas Huth                                    'find /sys/kernel/iommu_groups/ -type l',
109270d4a51SThomas Huth                                    'devices/0000:00:')
110270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
111270d4a51SThomas Huth
112270d4a51SThomas Huth        # Check hard disk device via sha256sum:
113270d4a51SThomas Huth        self.log.info("Checking hard disk...")
114270d4a51SThomas Huth        hashsum = '0dc7472f879be70b2f3daae279e3ae47175ffe249691e7d97f47222b65b8a720'
115270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'sha256sum ' + filename,
116270d4a51SThomas Huth                                          hashsum)
117270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
118270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'sha256sum /root/data',
119270d4a51SThomas Huth                                          hashsum)
120270d4a51SThomas Huth        self.wait_for_console_pattern(prompt)
121270d4a51SThomas Huth
122270d4a51SThomas Huth        # Check virtio-net via HTTP:
123270d4a51SThomas Huth        exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
124*2c92ecb6SThomas Huth        self.check_http_download(filename, hashsum, self.GUEST_PORT)
125270d4a51SThomas Huth
126270d4a51SThomas Huth    def test_intel_iommu(self):
127270d4a51SThomas Huth        self.common_vm_setup()
128270d4a51SThomas Huth        self.vm.add_args('-device', 'intel-iommu,intremap=on')
129270d4a51SThomas Huth        self.vm.add_args('-machine', 'kernel_irqchip=split')
130270d4a51SThomas Huth        self.kernel_params += 'intel_iommu=on'
131270d4a51SThomas Huth        self.run_and_check()
132270d4a51SThomas Huth
133270d4a51SThomas Huth    def test_intel_iommu_strict(self):
134270d4a51SThomas Huth        self.common_vm_setup()
135270d4a51SThomas Huth        self.vm.add_args('-device', 'intel-iommu,intremap=on')
136270d4a51SThomas Huth        self.vm.add_args('-machine', 'kernel_irqchip=split')
137270d4a51SThomas Huth        self.kernel_params += 'intel_iommu=on,strict'
138270d4a51SThomas Huth        self.run_and_check()
139270d4a51SThomas Huth
140270d4a51SThomas Huth    def test_intel_iommu_strict_cm(self):
141270d4a51SThomas Huth        self.common_vm_setup()
142270d4a51SThomas Huth        self.vm.add_args('-device', 'intel-iommu,intremap=on,caching-mode=on')
143270d4a51SThomas Huth        self.vm.add_args('-machine', 'kernel_irqchip=split')
144270d4a51SThomas Huth        self.kernel_params += 'intel_iommu=on,strict'
145270d4a51SThomas Huth        self.run_and_check()
146270d4a51SThomas Huth
147270d4a51SThomas Huth    def test_intel_iommu_pt(self):
148270d4a51SThomas Huth        self.common_vm_setup()
149270d4a51SThomas Huth        self.vm.add_args('-device', 'intel-iommu,intremap=on')
150270d4a51SThomas Huth        self.vm.add_args('-machine', 'kernel_irqchip=split')
151270d4a51SThomas Huth        self.kernel_params += 'intel_iommu=on iommu=pt'
152270d4a51SThomas Huth        self.run_and_check()
153270d4a51SThomas Huth
154270d4a51SThomas Huthif __name__ == '__main__':
155270d4a51SThomas Huth    LinuxKernelTest.main()
156