Skip to content

Commit 2a652f2

Browse files
committed
CPI: Add test case to check hypervisor bit of cpi info
Check hypervisor bit of cpi info when there's nested guest boot up and it will be changed as expected Signed-off-by: bfu <[email protected]>
1 parent 7881c71 commit 2a652f2

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

libvirt/tests/cfg/guest_kernel_debugging/cpi_info.cfg

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,6 @@
1616
- long_system_name:
1717
test_case_name = long_system_name
1818
test_system_name = "VERYLONGSYSTEMNAME123456789"
19+
- nested_kvm_cpi:
20+
test_case_name = nested_kvm_cpi
1921

libvirt/tests/src/guest_kernel_debugging/cpi_info.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import logging as log
22
import re
3+
import time
34

45
from virttest import utils_misc, virsh
6+
from avocado.utils import process
57
from virttest.utils_cpi import (
68
CPIChecker,
79
get_cpi_config,
@@ -298,6 +300,94 @@ def test_long_system_name(long_system_name):
298300

299301
logging.info("Long system name validation test passed")
300302

303+
def test_nested_kvm_cpi():
304+
"""
305+
Test case 4: Test CPI system_level behavior in nested KVM environment
306+
307+
Steps:
308+
1. L1 host: enable nested
309+
2. L2 guest: Check /sys/firmware/cpi/system_level and verify hypervisor_bit is '0'
310+
3. L2 guest: enable nested and Boot L3 guest
311+
4. L2 guest: Check /sys/firmware/cpi/system_level and verify hypervisor_bit is '1'
312+
"""
313+
logging.info("=== Test Case 4: Nested KVM CPI ===")
314+
315+
# Login L2 guest
316+
session = vm.wait_for_login(timeout=60)
317+
318+
def check_and_enable_nested(is_guest=False):
319+
current_nested = None
320+
try:
321+
if is_guest:
322+
# Check on L2 guest
323+
current_nested = session.cmd_output(
324+
"cat /sys/module/kvm/parameters/nested", timeout=30
325+
)
326+
logging.info(f"Current nested status: {current_nested}")
327+
else:
328+
# Check on L1 host
329+
current_nested = process.run(
330+
"cat /sys/module/kvm/parameters/nested", timeout=30
331+
)
332+
logging.info(f"Current nested status: {current_nested}")
333+
except Exception as e:
334+
logging.warning(f"Failed to check current nested status: {e}")
335+
336+
# Reload kvm module with nested=1 if not already enabled
337+
if current_nested != "1":
338+
logging.info("Reloading kvm module with nested=1")
339+
try:
340+
# Reload kvm modules with nested enabled
341+
if is_guest:
342+
# Reload on L2 guest
343+
session.cmd_output(
344+
"rmmod kvm ; modprobe kvm nested=1", timeout=30
345+
)
346+
# Verify nested is enabled
347+
current_nested = session.cmd_output(
348+
"cat /sys/module/kvm/parameters/nested", timeout=30
349+
)
350+
else:
351+
process.run(
352+
"rmmod kvm ; modprobe kvm nested=1", timeout=30
353+
)
354+
# Verify nested is enabled
355+
current_nested = process.run(
356+
"cat /sys/module/kvm/parameters/nested", timeout=30
357+
)
358+
if current_nested != "1":
359+
test.fail("Failed to enable nested virtualization")
360+
logging.info("Nested virtualization enabled successfully")
361+
except Exception as e:
362+
test.fail(f"Failed to reload kvm module: {e}")
363+
else:
364+
logging.info("Nested virtualization already enabled")
365+
366+
logging.info("Step 1: Enabling nested virtualization on L1 host")
367+
check_and_enable_nested(is_guest=False)
368+
369+
logging.info("Step 2: Checking CPI system_level on L2 guest")
370+
checker = CPIChecker(vm, serial=serial)
371+
system_level = checker.get_cpi_field("system_level")
372+
parsed = checker._parse_system_level(system_level)
373+
if parsed['hypervisor_bit'] != 0:
374+
test.fail(f"L2 hypervisor_bit should be 0, but actual is "
375+
f"{parsed['hypervisor_bit']}")
376+
377+
logging.info("Step 3: Enable nested on L2 guest and Boot L3 guest")
378+
check_and_enable_nested(is_guest=True)
379+
process.run(
380+
'/usr/libexec/qemu-kvm -machine s390-ccw-virtio -no-shutdown &')
381+
# wait L3 guest to boot up
382+
time.sleep(5)
383+
384+
logging.info("Step 4: Checking CPI system_level on L2 guest")
385+
system_level = checker.get_cpi_field("system_level")
386+
parsed = checker._parse_system_level(system_level)
387+
if parsed['hypervisor_bit'] != 1:
388+
test.fail(f"L2 hypervisor_bit should be 0, but actual is "
389+
f"{parsed['hypervisor_bit']}")
390+
301391
def cleanup_cpi_config():
302392
"""
303393
Clean up CPI configuration by restoring from backup
@@ -315,6 +405,8 @@ def cleanup_cpi_config():
315405
test_managedsave()
316406
elif test_case_name == "long_system_name":
317407
test_long_system_name(test_system_name)
408+
elif test_case_name == "nested_kvm_cpi":
409+
test_nested_kvm_cpi()
318410
else:
319411
test.error(f"Unknown test case: {test_case_name}")
320412

0 commit comments

Comments
 (0)