xref: /qemu/tests/functional/test_s390x_ccw_virtio.py (revision d986bc4a1c2de68dbb056b1b761a863dc47313ee)
1# Functional test that boots an s390x Linux guest with ccw and PCI devices
2# attached and checks whether the devices are recognized by Linux
3#
4# Copyright (c) 2020 Red Hat, Inc.
5#
6# Author:
7#  Cornelia Huck <cohuck@redhat.com>
8#
9# This work is licensed under the terms of the GNU GPL, version 2 or
10# later.  See the COPYING file in the top-level directory.
11
12
13from avocado_qemu import Test
14from avocado_qemu import exec_command_and_wait_for_pattern
15from avocado_qemu import wait_for_console_pattern
16
17class S390CCWVirtioMachine(Test):
18    KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
19
20    timeout = 120
21
22    def wait_for_console_pattern(self, success_message, vm=None):
23        wait_for_console_pattern(self, success_message,
24                                 failure_message='Kernel panic - not syncing',
25                                 vm=vm)
26
27    def wait_for_crw_reports(self):
28        exec_command_and_wait_for_pattern(self,
29                        'while ! (dmesg -c | grep CRW) ; do sleep 1 ; done',
30                        'CRW reports')
31
32    dmesg_clear_count = 1
33    def clear_guest_dmesg(self):
34        exec_command_and_wait_for_pattern(self, 'dmesg -c > /dev/null; '
35                    'echo dm_clear\ ' + str(self.dmesg_clear_count),
36                    'dm_clear ' + str(self.dmesg_clear_count))
37        self.dmesg_clear_count += 1
38
39    def test_s390x_devices(self):
40
41        """
42        :avocado: tags=arch:s390x
43        :avocado: tags=machine:s390-ccw-virtio
44        """
45
46        kernel_url = ('https://snapshot.debian.org/archive/debian/'
47                      '20201126T092837Z/dists/buster/main/installer-s390x/'
48                      '20190702+deb10u6/images/generic/kernel.debian')
49        kernel_hash = '5821fbee57d6220a067a8b967d24595621aa1eb6'
50        kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
51
52        initrd_url = ('https://snapshot.debian.org/archive/debian/'
53                      '20201126T092837Z/dists/buster/main/installer-s390x/'
54                      '20190702+deb10u6/images/generic/initrd.debian')
55        initrd_hash = '81ba09c97bef46e8f4660ac25b4ac0a5be3a94d6'
56        initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
57
58        self.vm.set_console()
59        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
60                              'console=sclp0 root=/dev/ram0 BOOT_DEBUG=3')
61        self.vm.add_args('-nographic',
62                         '-kernel', kernel_path,
63                         '-initrd', initrd_path,
64                         '-append', kernel_command_line,
65                         '-device', 'virtio-net-ccw,devno=fe.1.1111',
66                         '-device',
67                         'virtio-rng-ccw,devno=fe.2.0000,max_revision=0,id=rn1',
68                         '-device',
69                         'virtio-rng-ccw,devno=fe.3.1234,max_revision=2,id=rn2',
70                         '-device', 'zpci,uid=5,target=zzz',
71                         '-device', 'virtio-net-pci,id=zzz',
72                         '-device', 'zpci,uid=0xa,fid=12,target=serial',
73                         '-device', 'virtio-serial-pci,id=serial',
74                         '-device', 'virtio-balloon-ccw')
75        self.vm.launch()
76
77        shell_ready = "sh: can't access tty; job control turned off"
78        self.wait_for_console_pattern(shell_ready)
79        # first debug shell is too early, we need to wait for device detection
80        exec_command_and_wait_for_pattern(self, 'exit', shell_ready)
81
82        ccw_bus_ids="0.1.1111  0.2.0000  0.3.1234"
83        pci_bus_ids="0005:00:00.0  000a:00:00.0"
84        exec_command_and_wait_for_pattern(self, 'ls /sys/bus/ccw/devices/',
85                                          ccw_bus_ids)
86        exec_command_and_wait_for_pattern(self, 'ls /sys/bus/pci/devices/',
87                                          pci_bus_ids)
88        # check that the device at 0.2.0000 is in legacy mode, while the
89        # device at 0.3.1234 has the virtio-1 feature bit set
90        virtio_rng_features="00000000000000000000000000001100" + \
91                            "10000000000000000000000000000000"
92        virtio_rng_features_legacy="00000000000000000000000000001100" + \
93                                   "00000000000000000000000000000000"
94        exec_command_and_wait_for_pattern(self,
95                        'cat /sys/bus/ccw/devices/0.2.0000/virtio?/features',
96                        virtio_rng_features_legacy)
97        exec_command_and_wait_for_pattern(self,
98                        'cat /sys/bus/ccw/devices/0.3.1234/virtio?/features',
99                        virtio_rng_features)
100        # check that /dev/hwrng works - and that it's gone after ejecting
101        exec_command_and_wait_for_pattern(self,
102                        'dd if=/dev/hwrng of=/dev/null bs=1k count=10',
103                        '10+0 records out')
104        self.clear_guest_dmesg()
105        self.vm.command('device_del', id='rn1')
106        self.wait_for_crw_reports()
107        self.clear_guest_dmesg()
108        self.vm.command('device_del', id='rn2')
109        self.wait_for_crw_reports()
110        exec_command_and_wait_for_pattern(self,
111                        'dd if=/dev/hwrng of=/dev/null bs=1k count=10',
112                        'dd: /dev/hwrng: No such device')
113        # verify that we indeed have virtio-net devices (without having the
114        # virtio-net driver handy)
115        exec_command_and_wait_for_pattern(self,
116                                    'cat /sys/bus/ccw/devices/0.1.1111/cutype',
117                                    '3832/01')
118        exec_command_and_wait_for_pattern(self,
119                    'cat /sys/bus/pci/devices/0005\:00\:00.0/subsystem_vendor',
120                    '0x1af4')
121        exec_command_and_wait_for_pattern(self,
122                    'cat /sys/bus/pci/devices/0005\:00\:00.0/subsystem_device',
123                    '0x0001')
124        # check fid propagation
125        exec_command_and_wait_for_pattern(self,
126                        'cat /sys/bus/pci/devices/000a\:00\:00.0/function_id',
127                        '0x0000000c')
128        # add another device
129        self.clear_guest_dmesg()
130        self.vm.command('device_add', driver='virtio-net-ccw',
131                        devno='fe.0.4711', id='net_4711')
132        self.wait_for_crw_reports()
133        exec_command_and_wait_for_pattern(self, 'ls /sys/bus/ccw/devices/',
134                                          '0.0.4711')
135        # and detach it again
136        self.clear_guest_dmesg()
137        self.vm.command('device_del', id='net_4711')
138        self.vm.event_wait(name='DEVICE_DELETED',
139                           match={'data': {'device': 'net_4711'}})
140        self.wait_for_crw_reports()
141        exec_command_and_wait_for_pattern(self,
142                                          'ls /sys/bus/ccw/devices/0.0.4711',
143                                          'No such file or directory')
144        # test the virtio-balloon device
145        exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
146                                          'MemTotal:         115640 kB')
147        self.vm.command('human-monitor-command', command_line='balloon 96')
148        exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
149                                          'MemTotal:          82872 kB')
150        self.vm.command('human-monitor-command', command_line='balloon 128')
151        exec_command_and_wait_for_pattern(self, 'head -n 1 /proc/meminfo',
152                                          'MemTotal:         115640 kB')
153