22# SPDX-License-Identifier: Apache-2.0
33"""Tests on devices config space."""
44
5- import platform
65import random
7- import re
86import string
97import subprocess
108from threading import Thread
@@ -64,6 +62,8 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
6462
6563 net_addr_base = _get_net_mem_addr_base (ssh_conn , guest_if1_name )
6664 assert net_addr_base is not None
65+ config_offset = 0x4000 if test_microvm .pci_enabled else 0x100
66+ dev_addr = net_addr_base + config_offset
6767
6868 # Write into '/dev/mem' the same mac address, byte by byte.
6969 # This changes the MAC address physically, in the network device registers.
@@ -72,7 +72,7 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
7272 # `tx_spoofed_mac_count` metric shouldn't be incremented later on.
7373 rmt_path = "/tmp/change_net_config_space"
7474 test_microvm .ssh .scp_put (change_net_config_space_bin , rmt_path )
75- cmd = f"chmod u+x { rmt_path } && { rmt_path } { net_addr_base } { mac_hex } "
75+ cmd = f"chmod u+x { rmt_path } && { rmt_path } { dev_addr } { mac_hex } "
7676
7777 # This should be executed successfully.
7878 _ , stdout , _ = ssh_conn .check_output (cmd )
@@ -219,8 +219,7 @@ def _find_iomem_range(ssh_connection, dev_name):
219219 # its contents and grep for the VirtIO device name, which
220220 # with ACPI is "LNRO0005:XY".
221221 cmd = f"cat /proc/iomem | grep -m 1 { dev_name } "
222- rc , stdout , stderr = ssh_connection .run (cmd )
223- assert rc == 0 , stderr
222+ _ , stdout , _ = ssh_connection .check_output (cmd )
224223
225224 # Take range in the form 'start-end' from line. The line looks like this:
226225 # d00002000-d0002fff : LNRO0005:02
@@ -231,89 +230,16 @@ def _find_iomem_range(ssh_connection, dev_name):
231230 return (int (tokens [0 ], 16 ), int (tokens [1 ], 16 ))
232231
233232
234- def _get_net_mem_addr_base_x86_acpi (ssh_connection , if_name ):
235- """Check for net device memory start address via ACPI info"""
236- # On x86 we define VirtIO devices through ACPI AML bytecode. VirtIO devices
237- # are identified as "LNRO0005" and appear under /sys/devices/platform
238- sys_virtio_mmio_cmdline = "/sys/devices/platform/"
239- cmd = "ls {}"
240- _ , stdout , _ = ssh_connection .check_output (cmd .format (sys_virtio_mmio_cmdline ))
241- virtio_devs = list (filter (lambda x : "LNRO0005" in x , stdout .strip ().split ()))
242-
243- # For virtio-net LNRO0005 devices, we should have a path like:
244- # /sys/devices/platform/LNRO0005::XY/virtioXY/net which is a directory
245- # that includes a subdirectory `ethZ` which represents the network device
246- # that corresponds to the virtio-net device.
247- cmd = "ls {}/{}/virtio{}/net"
248- for idx , dev in enumerate (virtio_devs ):
249- _ , guest_if_name , _ = ssh_connection .run (
250- cmd .format (sys_virtio_mmio_cmdline , dev , idx )
251- )
252- if guest_if_name .strip () == if_name :
253- return _find_iomem_range (ssh_connection , dev )[0 ]
254-
255- return None
256-
257-
258- def _get_net_mem_addr_base_x86_cmdline (ssh_connection , if_name ):
259- """Check for net device memory start address via command line arguments"""
260- sys_virtio_mmio_cmdline = "/sys/devices/virtio-mmio-cmdline/"
261- cmd = "ls {} | grep virtio-mmio. | sed 's/virtio-mmio.//'"
262- exit_code , stdout , stderr = ssh_connection .run (cmd .format (sys_virtio_mmio_cmdline ))
263- assert exit_code == 0 , stderr
264- virtio_devs_idx = stdout .strip ().split ()
265-
266- cmd = "cat /proc/cmdline"
267- _ , cmd_line , _ = ssh_connection .check_output (cmd )
268- pattern_dev = re .compile ("(virtio_mmio.device=4K@0x[0-9a-f]+:[0-9]+)+" )
269- pattern_addr = re .compile ("virtio_mmio.device=4K@(0x[0-9a-f]+):[0-9]+" )
270- devs_addr = []
271- for dev in re .findall (pattern_dev , cmd_line ):
272- matched_addr = pattern_addr .search (dev )
273- # The 1st group which matches this pattern
274- # is the device start address. `0` group is
275- # full match
276- addr = matched_addr .group (1 )
277- devs_addr .append (addr )
278-
279- cmd = "ls {}/virtio-mmio.{}/virtio{}/net"
280- for idx in virtio_devs_idx :
281- _ , guest_if_name , _ = ssh_connection .run (
282- cmd .format (sys_virtio_mmio_cmdline , idx , idx )
283- )
284- if guest_if_name .strip () == if_name :
285- return devs_addr [int (idx )]
286-
287- return None
288-
289-
290233def _get_net_mem_addr_base (ssh_connection , if_name ):
291234 """Get the net device memory start address."""
292- if platform .machine () == "x86_64" :
293- acpi_info = _get_net_mem_addr_base_x86_acpi (ssh_connection , if_name )
294- if acpi_info is not None :
295- return acpi_info
296-
297- return _get_net_mem_addr_base_x86_cmdline (ssh_connection , if_name )
298-
299- if platform .machine () == "aarch64" :
300- sys_virtio_mmio_cmdline = "/sys/devices/platform"
301- cmd = "ls {} | grep .virtio_mmio" .format (sys_virtio_mmio_cmdline )
302- rc , stdout , _ = ssh_connection .run (cmd )
303- assert rc == 0
304-
305- virtio_devs = stdout .split ()
306- devs_addr = list (map (lambda dev : dev .split ("." )[0 ], virtio_devs ))
307-
308- cmd = "ls {}/{}/virtio{}/net"
309- # Device start addresses lack the hex prefix and are not interpreted
310- # accordingly when parsed inside `change_config_space.c`.
311- hex_prefix = "0x"
312- for idx , dev in enumerate (virtio_devs ):
313- _ , guest_if_name , _ = ssh_connection .run (
314- cmd .format (sys_virtio_mmio_cmdline , dev , idx )
315- )
316- if guest_if_name .strip () == if_name :
317- return hex_prefix + devs_addr [int (idx )]
318-
319- return None
235+ _ , stdout , _ = ssh_connection .check_output (f"find /sys/devices -name { if_name } " )
236+ device_paths = stdout .strip ().split ("\n " )
237+ assert (
238+ len (device_paths ) == 1
239+ ), f"No or multiple devices found for { if_name } :\n { stdout } "
240+ device_path = device_paths [0 ]
241+ parts = device_path .split ("/" )
242+ assert len (parts ) >= 6 , f"Unexpected device path: { device_path } "
243+ device = parts [- 4 ]
244+ start_addr , _ = _find_iomem_range (ssh_connection , device )
245+ return start_addr
0 commit comments