|
5 | 5 | import filecmp
|
6 | 6 | import logging
|
7 | 7 | import os
|
| 8 | +import platform |
8 | 9 | import re
|
9 | 10 | import shutil
|
10 | 11 | import time
|
11 | 12 | from pathlib import Path
|
12 | 13 |
|
13 | 14 | import pytest
|
14 | 15 |
|
| 16 | +import host_tools.cargo_build as host |
15 | 17 | import host_tools.drive as drive_tools
|
| 18 | +from framework import utils |
16 | 19 | from framework.microvm import SnapshotType
|
| 20 | +from framework.properties import global_props |
17 | 21 | from framework.utils import check_filesystem, check_output
|
18 | 22 | from framework.utils_vsock import (
|
19 | 23 | ECHO_SERVER_PORT,
|
@@ -540,3 +544,56 @@ def test_vmgenid(guest_kernel_linux_6_1, rootfs, microvm_factory, snapshot_type)
|
540 | 544 |
|
541 | 545 | # Update the base for next iteration
|
542 | 546 | base_snapshot = snapshot
|
| 547 | + |
| 548 | + |
| 549 | +# TODO add `global_props.host_os == "amzn2"` condition |
| 550 | +# once amazon linux kernels have patches. |
| 551 | +@pytest.mark.skipif( |
| 552 | + platform.machine() != "aarch64" or global_props.host_linux_version_tpl < (6, 4), |
| 553 | + reason="This is aarch64 specific test and should only be run on 6.4 and later kernels", |
| 554 | +) |
| 555 | +def test_physical_couter_reset_aarch64(uvm_nano): |
| 556 | + """ |
| 557 | + Test that the CNTPCT_EL0 register is reset on VM boot. |
| 558 | + We assume the smallest VM will not consume more than |
| 559 | + some MAX_VALUE cycles to be created and snapshotted. |
| 560 | + The MAX_VALUE is selected by doing a manual run of this test and |
| 561 | + seeing what the actual counter value is. The assumption here is that |
| 562 | + if resetting will not occur the guest counter value will be huge as it |
| 563 | + will be a copy of host value. The host value in its turn will be huge because |
| 564 | + it will include host OS boot + CI prep + other CI tests ... |
| 565 | + """ |
| 566 | + vm = uvm_nano |
| 567 | + vm.add_net_iface() |
| 568 | + vm.start() |
| 569 | + |
| 570 | + snapshot = vm.snapshot_full() |
| 571 | + vm.kill() |
| 572 | + snap_editor = host.get_binary("snapshot-editor") |
| 573 | + |
| 574 | + cntpct_el0 = hex(0x603000000013DF01) |
| 575 | + # If a CPU runs at 3GHz, it will have a counter value of 1_000_000_000 |
| 576 | + # in 1/3 of a second. The host surely will run for more than 1/3 second before |
| 577 | + # executing this test. |
| 578 | + max_value = 800_000_000 |
| 579 | + |
| 580 | + cmd = [ |
| 581 | + str(snap_editor), |
| 582 | + "info-vmstate", |
| 583 | + "vcpu-states", |
| 584 | + "--vmstate-path", |
| 585 | + str(snapshot.vmstate), |
| 586 | + ] |
| 587 | + _, stdout, _ = utils.check_output(cmd) |
| 588 | + |
| 589 | + # The output will look like this: |
| 590 | + # kvm_mp_state: 0x0 |
| 591 | + # mpidr: 0x80000000 |
| 592 | + # 0x6030000000100000 0x0000000e0 |
| 593 | + # 0x6030000000100002 0xffff00fe33c0 |
| 594 | + for line in stdout.splitlines(): |
| 595 | + parts = line.split() |
| 596 | + if len(parts) == 2: |
| 597 | + reg_id, reg_value = parts |
| 598 | + if reg_id == cntpct_el0: |
| 599 | + assert int(reg_value, 16) < max_value |
0 commit comments