2
2
# SPDX-License-Identifier: Apache-2.0
3
3
"""Tests on devices config space."""
4
4
5
- import platform
6
5
import random
7
- import re
8
6
import string
9
7
import subprocess
10
8
from threading import Thread
15
13
PAYLOAD_DATA_SIZE = 20
16
14
17
15
18
- def test_net_change_mac_address (uvm_plain_any , change_net_config_space_bin ):
16
+ def test_net_change_mac_address (
17
+ uvm_plain_any , pci_enabled , change_net_config_space_bin
18
+ ):
19
19
"""
20
20
Test changing the MAC address of the network device.
21
21
"""
22
22
23
23
test_microvm = uvm_plain_any
24
24
test_microvm .help .enable_console ()
25
- test_microvm .spawn ()
25
+ test_microvm .spawn (pci = pci_enabled )
26
26
test_microvm .basic_config (boot_args = "ipv6.disable=1" )
27
27
28
28
# Data exchange interface ('eth0' in guest).
@@ -64,6 +64,8 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
64
64
65
65
net_addr_base = _get_net_mem_addr_base (ssh_conn , guest_if1_name )
66
66
assert net_addr_base is not None
67
+ config_offset = 0x4000 if test_microvm .pci_enabled else 0x100
68
+ dev_addr = net_addr_base + config_offset
67
69
68
70
# Write into '/dev/mem' the same mac address, byte by byte.
69
71
# This changes the MAC address physically, in the network device registers.
@@ -72,7 +74,7 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
72
74
# `tx_spoofed_mac_count` metric shouldn't be incremented later on.
73
75
rmt_path = "/tmp/change_net_config_space"
74
76
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 } "
77
+ cmd = f"chmod u+x { rmt_path } && { rmt_path } { dev_addr } { mac_hex } "
76
78
77
79
# This should be executed successfully.
78
80
_ , stdout , _ = ssh_conn .check_output (cmd )
@@ -219,8 +221,7 @@ def _find_iomem_range(ssh_connection, dev_name):
219
221
# its contents and grep for the VirtIO device name, which
220
222
# with ACPI is "LNRO0005:XY".
221
223
cmd = f"cat /proc/iomem | grep -m 1 { dev_name } "
222
- rc , stdout , stderr = ssh_connection .run (cmd )
223
- assert rc == 0 , stderr
224
+ _ , stdout , _ = ssh_connection .check_output (cmd )
224
225
225
226
# Take range in the form 'start-end' from line. The line looks like this:
226
227
# d00002000-d0002fff : LNRO0005:02
@@ -231,89 +232,16 @@ def _find_iomem_range(ssh_connection, dev_name):
231
232
return (int (tokens [0 ], 16 ), int (tokens [1 ], 16 ))
232
233
233
234
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
-
290
235
def _get_net_mem_addr_base (ssh_connection , if_name ):
291
236
"""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
237
+ _ , stdout , _ = ssh_connection .check_output (f"find /sys/devices -name { if_name } " )
238
+ device_paths = stdout .strip ().split ("\n " )
239
+ assert (
240
+ len (device_paths ) == 1
241
+ ), f"No or multiple devices found for { if_name } :\n { stdout } "
242
+ device_path = device_paths [0 ]
243
+ parts = device_path .split ("/" )
244
+ assert len (parts ) >= 6 , f"Unexpected device path: { device_path } "
245
+ device = parts [- 4 ]
246
+ start_addr , _ = _find_iomem_range (ssh_connection , device )
247
+ return start_addr
0 commit comments