11import logging as log
22import re
3+ import time
34
45from virttest import utils_misc , virsh
6+ from avocado .utils import process
57from 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