Skip to content

Commit 4cf7900

Browse files
committed
acpi: fix test_net_change_mac_address test
This test is looking for the MMIO address range of virtio-net devices and then uses it to update the MAC address of the devices by writing under `/dev/mem`. The test was using the kernel command line to find the address range. With ACPI we don't pass this range via kernel command line any more, so adapt the test to look for this information under /proc/iomem. Signed-off-by: Babis Chalios <[email protected]>
1 parent 8e6c0df commit 4cf7900

File tree

1 file changed

+102
-28
lines changed

1 file changed

+102
-28
lines changed

tests/integration_tests/functional/test_net_config_space.py

Lines changed: 102 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
2121
"""
2222

2323
test_microvm = uvm_plain_any
24+
test_microvm.help.enable_console()
2425
test_microvm.spawn()
2526
test_microvm.basic_config(boot_args="ipv6.disable=1")
2627

@@ -196,37 +197,110 @@ def _change_guest_if_mac(ssh_connection, guest_if_mac, guest_if_name):
196197
ssh_connection.run(cmd)
197198

198199

200+
def _find_iomem_range(ssh_connection, dev_name):
201+
# `/proc/iomem` includes information of the system's MMIO registered
202+
# slots. It looks like this:
203+
#
204+
# ```
205+
# ~ cat /proc/iomem
206+
# 00000000-00000fff : Reserved
207+
# 00001000-0007ffff : System RAM
208+
# 00080000-0009ffff : Reserved
209+
# 000f0000-000fffff : System ROM
210+
# 00100000-0fffffff : System RAM
211+
# 01000000-018031d0 : Kernel code
212+
# 018031d1-01c863bf : Kernel data
213+
# 01df8000-0209ffff : Kernel bss
214+
# d0000000-d0000fff : LNRO0005:00
215+
# d0000000-d0000fff : LNRO0005:00
216+
# d0001000-d0001fff : LNRO0005:01
217+
# d0001000-d0001fff : LNRO0005:01
218+
# ```
219+
#
220+
# So, to find the address range of a device we just `cat`
221+
# its contents and grep for the VirtIO device name, which
222+
# with ACPI is "LNRO0005:XY".
223+
cmd = f"cat /proc/iomem | grep -m 1 {dev_name}"
224+
rc, stdout, stderr = ssh_connection.run(cmd)
225+
assert rc == 0, stderr
226+
227+
# Take range in the form 'start-end' from line. The line looks like this:
228+
# d00002000-d0002fff : LNRO0005:02
229+
mem_range = stdout.strip().split(" ")[0]
230+
231+
# Parse range into (start, end) integers
232+
tokens = mem_range.split("-")
233+
return (int(tokens[0], 16), int(tokens[1], 16))
234+
235+
236+
def _get_net_mem_addr_base_x86_acpi(ssh_connection, if_name):
237+
"""Check for net device memory start address via ACPI info"""
238+
# On x86 we define VirtIO devices through ACPI AML bytecode. VirtIO devices
239+
# are identified as "LNRO0005" and appear under /sys/devices/platform
240+
sys_virtio_mmio_cmdline = "/sys/devices/platform/"
241+
cmd = "ls {}"
242+
exit_code, stdout, stderr = ssh_connection.run(cmd.format(sys_virtio_mmio_cmdline))
243+
assert exit_code == 0, stderr
244+
virtio_devs = list(filter(lambda x: "LNRO0005" in x, stdout.strip().split()))
245+
246+
# For virtio-net LNRO0005 devices, we should have a path like:
247+
# /sys/devices/platform/LNRO0005::XY/virtioXY/net which is a directory
248+
# that includes a subdirectory `ethZ` which represents the network device
249+
# that corresponds to the virtio-net device.
250+
cmd = "ls {}/{}/virtio{}/net"
251+
for idx, dev in enumerate(virtio_devs):
252+
_, guest_if_name, _ = ssh_connection.run(
253+
cmd.format(sys_virtio_mmio_cmdline, dev, idx)
254+
)
255+
if guest_if_name.strip() == if_name:
256+
return _find_iomem_range(ssh_connection, dev)[0]
257+
258+
return None
259+
260+
261+
def _get_net_mem_addr_base_x86_cmdline(ssh_connection, if_name):
262+
"""Check for net device memory start address via command line arguments"""
263+
sys_virtio_mmio_cmdline = "/sys/devices/virtio-mmio-cmdline/"
264+
cmd = "ls {} | grep virtio-mmio. | sed 's/virtio-mmio.//'"
265+
exit_code, stdout, stderr = ssh_connection.run(cmd.format(sys_virtio_mmio_cmdline))
266+
assert exit_code == 0, stderr
267+
virtio_devs_idx = stdout.strip().split()
268+
269+
cmd = "cat /proc/cmdline"
270+
exit_code, cmd_line, stderr = ssh_connection.run(cmd)
271+
assert exit_code == 0, stderr
272+
pattern_dev = re.compile("(virtio_mmio.device=4K@0x[0-9a-f]+:[0-9]+)+")
273+
pattern_addr = re.compile("virtio_mmio.device=4K@(0x[0-9a-f]+):[0-9]+")
274+
devs_addr = []
275+
for dev in re.findall(pattern_dev, cmd_line):
276+
matched_addr = pattern_addr.search(dev)
277+
# The 1st group which matches this pattern
278+
# is the device start address. `0` group is
279+
# full match
280+
addr = matched_addr.group(1)
281+
devs_addr.append(addr)
282+
283+
cmd = "ls {}/virtio-mmio.{}/virtio{}/net"
284+
for idx in virtio_devs_idx:
285+
_, guest_if_name, _ = ssh_connection.run(
286+
cmd.format(sys_virtio_mmio_cmdline, idx, idx)
287+
)
288+
if guest_if_name.strip() == if_name:
289+
return devs_addr[int(idx)]
290+
291+
return None
292+
293+
199294
def _get_net_mem_addr_base(ssh_connection, if_name):
200295
"""Get the net device memory start address."""
201296
if platform.machine() == "x86_64":
202-
sys_virtio_mmio_cmdline = "/sys/devices/virtio-mmio-cmdline/"
203-
cmd = "ls {} | grep virtio-mmio. | sed 's/virtio-mmio.//'"
204-
exit_code, stdout, _ = ssh_connection.run(cmd.format(sys_virtio_mmio_cmdline))
205-
assert exit_code == 0
206-
virtio_devs_idx = stdout.split()
207-
208-
cmd = "cat /proc/cmdline"
209-
exit_code, cmd_line, _ = ssh_connection.run(cmd)
210-
assert exit_code == 0
211-
pattern_dev = re.compile("(virtio_mmio.device=4K@0x[0-9a-f]+:[0-9]+)+")
212-
pattern_addr = re.compile("virtio_mmio.device=4K@(0x[0-9a-f]+):[0-9]+")
213-
devs_addr = []
214-
for dev in re.findall(pattern_dev, cmd_line):
215-
matched_addr = pattern_addr.search(dev)
216-
# The 1st group which matches this pattern
217-
# is the device start address. `0` group is
218-
# full match.
219-
addr = matched_addr.group(1)
220-
devs_addr.append(addr)
221-
222-
cmd = "ls {}/virtio-mmio.{}/virtio{}/net"
223-
for idx in virtio_devs_idx:
224-
_, guest_if_name, _ = ssh_connection.run(
225-
cmd.format(sys_virtio_mmio_cmdline, idx, idx)
226-
)
227-
if guest_if_name.strip() == if_name:
228-
return devs_addr[int(idx)]
229-
elif platform.machine() == "aarch64":
297+
acpi_info = _get_net_mem_addr_base_x86_acpi(ssh_connection, if_name)
298+
if acpi_info is not None:
299+
return acpi_info
300+
301+
return _get_net_mem_addr_base_x86_cmdline(ssh_connection, if_name)
302+
303+
if platform.machine() == "aarch64":
230304
sys_virtio_mmio_cmdline = "/sys/devices/platform"
231305
cmd = "ls {} | grep .virtio_mmio".format(sys_virtio_mmio_cmdline)
232306
rc, stdout, _ = ssh_connection.run(cmd)

0 commit comments

Comments
 (0)