Skip to content

Conversation

zixi-chen
Copy link
Contributor

@zixi-chen zixi-chen commented Aug 8, 2025

ID: 4345

Summary by CodeRabbit

  • New Features

    • Added multi-VM TDX test variants (single, four, dynamic max-VM sizing)
    • Added host/guest attestation workflow and a helper attestation script
    • Configurable TDX options including socket-based quote exchange and kernel params
  • Tests

    • Introduced automated multi-VM TDX test covering VM lifecycle, guest verification, attestation execution, and cleanup across variants

@zixi-chen
Copy link
Contributor Author

@XueqiangWei @zhencliu Could you please help to review this patch?

@XueqiangWei
Copy link
Contributor

@zixi-chen Can you help add the test results? Thanks.

@zixi-chen
Copy link
Contributor Author

@zixi-chen Can you help add the test results? Thanks.

Test results are added to ticket 4345, thanks.

@coderabbitai
Copy link

coderabbitai bot commented Oct 22, 2025

Walkthrough

Adds TDX attestation components: a new shell attestation script, a QEMU test configuration for multi-VM TDX scenarios (single_vcpu, four_vms, max_vms), and a Python test that provisions multiple VMs, verifies guest TDX state, runs attestation, and ensures cleanup.

Changes

Cohort / File(s) Change Summary
TDX Attestation Script
qemu/deps/tdx/attestation.sh
New shell script: enables set -e, creates TSM report dir, writes 64 bytes of random inblob, dumps outblob hex, downloads a Python helper via wget, installs Python deps (ecdsa, pyopenssl, pyasn1_modules), and runs the helper against the report outblob.
TDX Multi-VM Test Config
qemu/tests/cfg/tdx_multi_vms.cfg
New QEMU test config for Linux hosts: defines tdx_multi_vms with kernel/module params, TDX module paths, attestation script/guest/host script settings, and three variants (single_vcpu, four_vms, max_vms) controlling VM count, CPU topology, and memory.
TDX Multi-VM Test Module
qemu/tests/tdx_multi_vms.py
New Python test module: checks host TDX support, determines VM/count and vCPU distribution via max_vms_cmd/max_vcpu_cmd, adjusts per-VM memory, creates and boots VMs, verifies TDX inside guests, copies and executes attestation workflows (guest + host scripts), handles failures, and performs cleanup.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Runner as Test Runner
    participant Host as Host
    participant Controller as Test Module
    participant VM as VM Instance
    participant Guest as Guest OS
    participant Script as attestation.sh
    participant Py as tdx.py

    Runner->>Host: check tdx_module_path (host capability)
    Host-->>Runner: capability OK / cancel

    Controller->>Host: run max_vms_cmd / max_vcpu_cmd
    Host-->>Controller: num_vms & smp info

    Controller->>VM: create & start VMs (distribute smp/mem)
    VM-->>Controller: booted / alive

    Controller->>Guest: open session & run tdx_guest_check
    Guest-->>Controller: verification result

    alt Verified
        Controller->>Guest: copy `host_script` & `attestation.sh`
        Controller->>Guest: set perms & run `guest_cmd`
        Guest->>Script: invoke attestation.sh (generate report, write inblob)
        Script->>Py: download & execute Python attestation helper with outblob
        Py-->>Script: attestation result
        Script-->>Guest: output result
    else Failed
        Controller-->>Runner: mark test failed
    end

    Controller->>VM: destroy VMs
    Controller->>Guest: close sessions
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 I tunneled through code to spawn each VM,
Random seeds scattered where the outblobs stem,
A tiny shell fetched Python to play,
Guests checked their TDX and saved the day,
Hops, scripts, and reports — attestation gem.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "Tdx guest: multi guests boot with attestation" accurately reflects the main changes in the PR. All three files added (attestation.sh script, tdx_multi_vms.cfg configuration, and tdx_multi_vms.py test module) are specifically designed to implement a test scenario where multiple TDX guest VMs boot and perform attestation operations. The title is clear, specific, and concise—it explicitly mentions the key aspects of the change (multi guests, boot, attestation) without vague terminology. A teammate reviewing the commit history would clearly understand that this PR adds functionality for testing multiple TDX guests with attestation capability.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (3)
qemu/tests/cfg/tdx_multi_vms.cfg (2)

14-14: Make the guest dmesg check more robust and quiet.

Prefer restricting to kernel logs and suppressing pager/noise.

Apply:

-    tdx_guest_check = "journalctl|grep -i -w tdx"
+    tdx_guest_check = journalctl -k --no-pager | grep -iqw tdx

21-34: Align VM naming and sources of truth for multi‑VM counts.

Variants define vms as vm2/vm3/vm4 while the Python test may append vm_1..vm_{N-1} when num_vms is set (32_vms). Mixing styles risks mismatches.

  • Use a single strategy: either fully declare vms in cfg per variant, or let the test compute and set them consistently (vm1..vmN).
  • If keeping dynamic creation for 32_vms, standardize on vm1..vm32 (no underscores) to match other variants.
qemu/tests/tdx_multi_vms.py (1)

28-28: Fix log banner typo.

It should be TDX only.

Apply:

-    error_context.context("Start sev-tdx test", test.log.info)
+    error_context.context("Start TDX test", test.log.info)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 02fbc5f and c256bcb.

📒 Files selected for processing (3)
  • qemu/deps/tdx/attestation.sh (1 hunks)
  • qemu/tests/cfg/tdx_multi_vms.cfg (1 hunks)
  • qemu/tests/tdx_multi_vms.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
qemu/tests/tdx_multi_vms.py (1)
generic/tests/trans_hugepage_swapping.py (1)
  • get_mem_info (21-29)
🪛 Shellcheck (0.11.0)
qemu/deps/tdx/attestation.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🔇 Additional comments (1)
qemu/tests/cfg/tdx_multi_vms.cfg (1)

10-10: Remove concern; quoting is consistent with repository convention.

Double-quoted values for machine_type_extra_params align with the established pattern across the codebase. A search of existing configs reveals ~42 instances use double quotes (including similar params like "kernel-irqchip=split"), with only 3 unquoted outliers. The current usage at line 10 is correct and follows the standard.

Likely an incorrect or invalid review comment.

@@ -0,0 +1,8 @@
set -e
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add a shebang and stricter shell options.

Current script has no shebang and only set -e. Add bash shebang and safer defaults.

Apply:

+#!/usr/bin/env bash
-set -e
+set -Eeuo pipefail
+IFS=$'\n\t'

Based on ShellCheck SC2148 hint.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
set -e
#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'
🧰 Tools
🪛 Shellcheck (0.11.0)

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🤖 Prompt for AI Agents
In qemu/deps/tdx/attestation.sh around line 1, the script currently only has
"set -e" and lacks a shebang and stricter shell options; add a bash shebang
(e.g. #!/usr/bin/env bash) as the first line and replace or augment the options
with safer defaults such as set -euo pipefail (and optionally set IFS=$'\n\t' if
the script relies on word-splitting safety), ensuring the file remains
executable.

Comment on lines +2 to +5
report=/sys/kernel/config/tsm/report/report0
mkdir $report
dd if=/dev/urandom bs=64 count=1 > $report/inblob
hexdump -C $report/outblob
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Harden configfs use and avoid brittle mkdir/expansions.

  • mkdir without -p fails if report exists (and exits due to set -e).
  • Unquoted expansions.
  • No check that configfs/tsm path exists/mounted.

Apply:

-report=/sys/kernel/config/tsm/report/report0
-mkdir $report
-dd if=/dev/urandom bs=64 count=1 > $report/inblob
-hexdump -C $report/outblob
+report=/sys/kernel/config/tsm/report/report0
+report_dir="$(dirname "$report")"
+mkdir -p "$report"
+# Generate exactly 64 bytes for inblob
+dd if=/dev/urandom bs=64 count=1 status=none > "$report/inblob"
+# Optional: avoid dumping the full outblob into logs; print size only
+# hexdump -C "$report/outblob"
+stat -c 'outblob size: %s bytes' "$report/outblob" || true

(Optional) Add a preflight check for configfs/tsm and mount if needed.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In qemu/deps/tdx/attestation.sh around lines 2 to 5, the script uses brittle
unquoted expansions and a plain mkdir which will fail under set -e if the
directory already exists, and it doesn't verify that configfs/tsm is present or
mounted. Change mkdir to mkdir -p and quote all variable expansions (e.g.
"$report" and "$report/inblob") everywhere; add a preflight check that the
configfs base (e.g. /sys/kernel/config/tsm) exists and is a mountpoint (and
attempt to mount configfs if absent) before creating the report directory; and
check for successful creation/writability before writing with dd and reading
with hexdump, failing with a clear message if any step fails.

Comment on lines +6 to +8
wget https://file.rdu.redhat.com/~berrange/tdx.py
pip install ecdsa pyopenssl pyasn1_modules
python tdx.py $report/outblob
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Blocker: remote code execution and global pip installs.

Downloading and executing tdx.py from a remote URL at runtime, plus unconstrained global pip installs, are high‑risk (supply chain, reproducibility, network fragility). Use a vendored script and an isolated venv pinned to versions/hashes.

Apply:

-wget https://file.rdu.redhat.com/~berrange/tdx.py
-pip install ecdsa pyopenssl pyasn1_modules
-python tdx.py $report/outblob
+# Use vendored script and pinned deps
+# (example paths assuming this lives in qemu/deps/tdx/)
+script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+tdx_py="$script_dir/tdx.py"
+reqs="$script_dir/requirements.txt"
+venv_dir="${TMPDIR:-/tmp}/tdx-attest-venv"
+python3 -m venv "$venv_dir"
+"$venv_dir/bin/python" -m pip install --no-input --upgrade pip
+"$venv_dir/bin/python" -m pip install --no-input -r "$reqs"
+"$venv_dir/bin/python" "$tdx_py" "$report/outblob"

Also pin package versions in requirements.txt and consider integrity verification (hash‑pinned installs).

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In qemu/deps/tdx/attestation.sh around lines 6–8, do not wget and exec a remote
tdx.py or run global pip installs; instead vendor the tdx.py into the repo
(e.g., qemu/deps/tdx/tdx.py) and update the script to create and activate a
python virtualenv before installing dependencies; move dependencies to a
requirements.txt with pinned versions (and ideally hashes) and install them into
the venv via pip install --require-hashes -r requirements.txt; ensure the script
invokes the vendored tdx.py from the venv Python interpreter and remove any
global pip usage or network-executed code.

Comment on lines 50 to 55
if params.get_numeric("smp") > 1:
MemFree = float(
normalize_data_size("%s KB" % get_mem_info(attr="MemFree"), "M")
)
vm_num = len(params.get("vms").split())
params["mem"] = MemFree // (2 * vm_num)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Memory calc: confirm API and ensure integer MiB.

  • get_mem_info(attr="MemFree") signature may differ; confirm correct import.
  • params["mem"] becomes a float; pass an int MiB.

Apply:

-    MemFree = float(
-        normalize_data_size("%s KB" % get_mem_info(attr="MemFree"), "M")
-    )
+    MemFree = int(float(normalize_data_size(f"{get_mem_info(attr='MemFree')} KB", "M")))
     vm_num = len(params.get("vms").split())
-    params["mem"] = MemFree // (2 * vm_num)
+    params["mem"] = int(MemFree // (2 * vm_num))

Verify the function signature in your tree:


🏁 Script executed:

#!/bin/bash
rg -nC2 -P 'def\s+get_mem_info\s*\('

Length of output: 338



🏁 Script executed:

#!/bin/bash
# Find all get_mem_info definitions in the codebase
rg -n 'def\s+get_mem_info' --type=py

# Also check imports in the file under review
echo "--- Imports in tdx_multi_vms.py ---"
head -30 qemu/tests/tdx_multi_vms.py | grep -E '^(import|from)'

Length of output: 294



🏁 Script executed:

#!/bin/bash
# Get full import block from tdx_multi_vms.py
head -40 qemu/tests/tdx_multi_vms.py

# Check if get_mem_info is defined or imported in virttest modules
echo "--- Searching for get_mem_info in virttest ---"
rg -n 'get_mem_info' --type=py | grep -E '(virttest|def|import)' | head -20

Length of output: 1611



🏁 Script executed:

#!/bin/bash
# Search for get_mem_info in virttest directory specifically
rg -n 'def\s+get_mem_info' --type=py | grep virttest

# Also try to find the virttest module path and check utils_misc
fd -t f 'utils_misc' 2>/dev/null | head -10

# Search with more context around get_mem_info definitions
rg -nB2 -A5 'def\s+get_mem_info\s*\(' --type=py

Length of output: 539



🌐 Web query:

virttest.utils_misc get_mem_info function signature

💡 Result:

Which virttest version do you need the get_mem_info signature for? (e.g. the ReadTheDocs release, a GitHub commit/tag, or your local install)



🏁 Script executed:

#!/bin/bash
# Verify the float division behavior and check if params["mem"] is expected to be int
# Search for how params["mem"] is used elsewhere
rg -n 'params\["mem"\]' --type=py -C2 | head -40

# Also check if there are other assignments to params["mem"] in this file
grep -n 'params\[.*mem.*\]' qemu/tests/tdx_multi_vms.py

Length of output: 2607



🏁 Script executed:

#!/bin/bash
# Check the context around snp_multi_vm.py lines 40-50 to verify identical pattern
sed -n '40,50p' qemu/tests/snp_multi_vm.py

# Also check if snp_multi_vm.py has any fixes or different approach
rg -n 'MemFree' qemu/tests/snp_multi_vm.py -B3 -A3

Length of output: 856


Float division produces float instead of int; fix confirmed necessary.

The review comment correctly identifies a real issue. In Python, float // int returns a float, not an int. Since MemFree is explicitly cast to float (lines 50-52), the expression MemFree // (2 * vm_num) on line 55 produces a float. This is inconsistent with expected usage elsewhere in the codebase where params["mem"] is routinely cast to int before use (e.g., hugepage_reset.py:87, mlock_basic.py:20). The identical code pattern exists in snp_multi_vm.py:47.

Regarding get_mem_info(attr="MemFree"): The import is confirmed as from virttest.utils_misc import get_mem_info, and the keyword argument usage is consistent across multiple test files. The function signature cannot be verified from the repository alone, but the pattern suggests it is supported.

The suggested fix is mostly correct; however, int(float(...)) can be simplified to int(...) without the intermediate float conversion.

🤖 Prompt for AI Agents
In qemu/tests/tdx_multi_vms.py around lines 50-56, MemFree is cast to float
which makes the floor-division produce a float; replace the float conversion
with an integer conversion so MemFree becomes an int (e.g., use
int(normalize_data_size(..., "M"))) and keep params["mem"] = MemFree // (2 *
vm_num) to yield an int; apply the same change to the identical pattern in
snp_multi_vm.py at the corresponding line (around line 47).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (4)
qemu/deps/tdx/attestation.sh (1)

1-8: Past critical issues remain unaddressed.

The following critical security and reliability issues previously flagged in past reviews remain unresolved:

  1. Line 1: Missing shebang and insufficient error handling (only set -e).
  2. Lines 2-5: Unquoted variable expansions and mkdir without -p flag, causing brittleness.
  3. Lines 6-8: Remote code execution via wget, global pip installs, and execution of unverified script—a supply chain security risk.

Please address the previously documented concerns before proceeding.

qemu/tests/tdx_multi_vms.py (3)

40-47: Guard against insufficient CPUs and verify VM count calculation.

The previously flagged issue persists: if max_smp < max_vms, the division on line 47 produces smp=0, causing VM preparation to fail.

Additionally, verify the VM count logic: range(1, max_vms) creates max_vms - 1 VMs, which when combined with existing VMs may not match the divisor max_vms on line 47.

Apply this diff to add the CPU guard:

     if max_vms_cmd:
         max_vms = int(process.system_output(max_vms_cmd, shell=True))
         for i in range(1, max_vms):
             params["vms"] += " vm_%s" % i
         max_smp = int(process.system_output(params["max_vcpu_cmd"], shell=True))
+        if max_smp < max_vms:
+            test.cancel(f"Not enough CPUs ({max_smp}) to split across {max_vms} VMs")
         params["smp"] = max_smp // max_vms

50-55: Memory calculation produces float instead of int.

The previously flagged issue persists: since MemFree is cast to float (line 51), the floor division on line 55 produces a float rather than an int, which is inconsistent with how params["mem"] is used elsewhere in the codebase.

Apply this diff:

     if params.get_numeric("smp") > 1:
-        MemFree = float(
-            normalize_data_size("%s KB" % get_mem_info(attr="MemFree"), "M")
-        )
+        MemFree = int(normalize_data_size("%s KB" % get_mem_info(attr="MemFree"), "M"))
         vm_num = len(params.get("vms").split())
-        params["mem"] = MemFree // (2 * vm_num)
+        params["mem"] = int(MemFree // (2 * vm_num))

65-92: Undefined session variable in finally block.

The previously flagged issue persists: if wait_for_login() (line 68) raises an exception, session remains undefined, causing the finally block (line 91) to fail when attempting session.close(), which masks the original error.

Apply this diff:

     for vm in vms_queue:
         vm.verify_alive()
         verify_dmesg()
+        session = None
-        session = vm.wait_for_login(timeout=timeout)
-        guest_check_cmd = params["tdx_guest_check"]
         try:
+            session = vm.wait_for_login(timeout=timeout)
+            guest_check_cmd = params["tdx_guest_check"]
             session.cmd_output(guest_check_cmd, timeout=240)
         except Exception as e:
             test.fail("Guest tdx verify fail: %s" % str(e))
         else:
             # Verify attestation
             ...
         finally:
-            session.close()
+            if session:
+                session.close()
             vm.destroy()
🧹 Nitpick comments (1)
qemu/tests/cfg/tdx_multi_vms.cfg (1)

11-11: Consider making the BIOS path configurable.

The hardcoded path /usr/share/edk2/ovmf/OVMF.inteltdx.fd may not exist on all systems. If tests need to run across different environments, consider making this configurable via an environment variable or allowing override from a separate config.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c256bcb and 1df9a23.

📒 Files selected for processing (3)
  • qemu/deps/tdx/attestation.sh (1 hunks)
  • qemu/tests/cfg/tdx_multi_vms.cfg (1 hunks)
  • qemu/tests/tdx_multi_vms.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
qemu/tests/tdx_multi_vms.py (1)
generic/tests/trans_hugepage_swapping.py (1)
  • get_mem_info (21-29)
🪛 Shellcheck (0.11.0)
qemu/deps/tdx/attestation.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🔇 Additional comments (2)
qemu/tests/tdx_multi_vms.py (2)

57-64: VM creation flow is well-structured.

The preprocessing, retrieval, queuing, and creation sequence is clean and follows expected patterns.


67-67: Clarify the intent of verify_dmesg() call.

The verify_dmesg() call appears to check the host's dmesg, not the guest's. If the intent is to verify TDX-related messages in the guest, this should be run via the guest session after login. If checking host dmesg for each VM is intentional, consider moving it outside the loop or adding a comment to clarify.

tdx_module_path = "/sys/module/kvm_intel/parameters/tdx"
module_status = Y y 1
tdx_guest_check = "journalctl|grep -i -w tdx"
# guest_tool_install = "dnf install -y tdxguesddt"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix the typo in the commented package name.

The package name appears to contain a typo: tdxguesddt should likely be tdxguestddt or similar. Even though this line is commented out, correcting it ensures accuracy when it's eventually enabled.

Apply this diff:

-#    guest_tool_install = "dnf install -y tdxguesddt"
+#    guest_tool_install = "dnf install -y tdxguestddt"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# guest_tool_install = "dnf install -y tdxguesddt"
# guest_tool_install = "dnf install -y tdxguestddt"
🤖 Prompt for AI Agents
In qemu/tests/cfg/tdx_multi_vms.cfg around line 15, the commented package name
contains a typo `tdxguesddt`; update the comment to the correct package name
(e.g., `tdxguestddt`) so the line reads `#    guest_tool_install = "dnf install
-y tdxguestddt"` to ensure accuracy when uncommented.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (4)
qemu/deps/tdx/attestation.sh (3)

1-1: Add shebang and stricter shell options.

The script lacks a shebang and uses only set -e. Add a bash shebang as the first line and consider stricter options like set -euo pipefail.

As per static analysis hints.


2-5: Harden configfs usage and quote variable expansions.

The mkdir command will fail if the directory exists (combined with set -e), variable expansions are unquoted, and there's no verification that configfs/tsm is mounted.


6-8: Eliminate remote code execution and global pip installs.

Downloading and executing a script from a remote URL introduces supply-chain risks, and global pip installs lack version control and isolation. Vendor the script into the repository and use a virtual environment with pinned dependencies.

qemu/tests/tdx_multi_vms.py (1)

64-91: Critical: Finally block will raise AttributeError if session is None.

While session = None is correctly initialized at line 67, the finally block at line 90 calls session.close() unconditionally. If wait_for_login() raises an exception, session remains None and session.close() will raise AttributeError, masking the original error.

Apply this diff:

     for vm in vms_queue:
         vm.verify_alive()
         guest_check_cmd = params["tdx_guest_check"]
         session = None
         try:
             session = vm.wait_for_login(timeout=timeout)
             session.cmd_output(guest_check_cmd, timeout=240)
         except Exception as e:
             test.fail("Guest tdx verify fail: %s" % str(e))
         else:
             # Verify attestation
             error_context.context("Start to do attestation", test.log.info)
             guest_dir = params["guest_dir"]
             host_script = params["host_script"]
             guest_cmd = params["guest_cmd"]
             deps_dir = virttest_data_dir.get_deps_dir()
             host_file = os.path.join(deps_dir, host_script)
             try:
                 vm.copy_files_to(host_file, guest_dir)
                 session.cmd_output("chmod 755 %s" % guest_cmd)
             except Exception as e:
                 test.fail("Guest test preparation fail: %s" % str(e))
             s = session.cmd_status(guest_cmd, timeout=360)
             if s:
                 test.fail("Guest script error")
         finally:
-            session.close()
+            if session:
+                session.close()
             vm.destroy()
🧹 Nitpick comments (1)
qemu/tests/tdx_multi_vms.py (1)

49-54: Consider converting MemFree to int directly.

While the current code correctly produces an integer for params["mem"], converting MemFree to int directly would be cleaner and avoid the intermediate float.

Apply this diff:

     if params.get_numeric("smp") > 1:
-        MemFree = float(
+        MemFree = int(
             normalize_data_size("%s KB" % get_mem_info(attr="MemFree"), "M")
         )
         vm_num = len(params.get("vms").split())
-        params["mem"] = int(MemFree // (2 * vm_num))
+        params["mem"] = MemFree // (2 * vm_num)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1df9a23 and 289a5eb.

📒 Files selected for processing (3)
  • qemu/deps/tdx/attestation.sh (1 hunks)
  • qemu/tests/cfg/tdx_multi_vms.cfg (1 hunks)
  • qemu/tests/tdx_multi_vms.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • qemu/tests/cfg/tdx_multi_vms.cfg
🧰 Additional context used
🧬 Code graph analysis (1)
qemu/tests/tdx_multi_vms.py (1)
generic/tests/trans_hugepage_swapping.py (1)
  • get_mem_info (21-29)
🪛 Shellcheck (0.11.0)
qemu/deps/tdx/attestation.sh

[error] 1-1: Tips depend on target shell and yours is unknown. Add a shebang or a 'shell' directive.

(SC2148)

🔇 Additional comments (3)
qemu/tests/tdx_multi_vms.py (3)

12-28: LGTM: Function structure and initial setup.

The test function is properly decorated with @error_context.context_aware, includes clear documentation, and correctly identifies itself as a TDX test.


30-37: LGTM: Host capability check.

The TDX module presence and status verification correctly uses test.cancel when host support is missing.


56-62: LGTM: VM preparation and creation.

The VM preprocessing and creation loop follows the standard pattern for multi-VM scenarios.

@zixi-chen
Copy link
Contributor Author

@XueqiangWei @PaulYuuu Could you please review the patch? Test result is updated in the ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants