@@ -21,6 +21,7 @@ def test_net_change_mac_address(uvm_plain_any, change_net_config_space_bin):
21
21
"""
22
22
23
23
test_microvm = uvm_plain_any
24
+ test_microvm .help .enable_console ()
24
25
test_microvm .spawn ()
25
26
test_microvm .basic_config (boot_args = "ipv6.disable=1" )
26
27
@@ -196,37 +197,110 @@ def _change_guest_if_mac(ssh_connection, guest_if_mac, guest_if_name):
196
197
ssh_connection .run (cmd )
197
198
198
199
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
+
199
294
def _get_net_mem_addr_base (ssh_connection , if_name ):
200
295
"""Get the net device memory start address."""
201
296
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" :
230
304
sys_virtio_mmio_cmdline = "/sys/devices/platform"
231
305
cmd = "ls {} | grep .virtio_mmio" .format (sys_virtio_mmio_cmdline )
232
306
rc , stdout , _ = ssh_connection .run (cmd )
0 commit comments