-
Notifications
You must be signed in to change notification settings - Fork 183
windows_update_perf: support VBS #4332
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
xiagao
wants to merge
1
commit into
autotest:master
Choose a base branch
from
xiagao:bz3886_vbs
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| - win_virtio_perf_test: | ||
| only q35 | ||
| only ovmf | ||
| no RHEL, Win10, Win11 | ||
| type = win_virtio_perf_test | ||
| login_timeout = 720 | ||
| start_vm = no | ||
| auto_cpu_model = yes | ||
| clone_master = yes | ||
| master_images_clone = image1 | ||
| force_image_clone = yes | ||
| remove_image_image1 = yes | ||
| # support nested virtualization | ||
| HostCpuVendor.intel: | ||
| cpu_model_flags += ',vmx=on' | ||
| HostCpuVendor.amd: | ||
| cpu_model_flags += ',svm=on' | ||
| restore_ovmf_vars = yes | ||
| check_secure_boot_enabled_cmd = 'powershell -command "Confirm-SecureBootUEFI"' | ||
| dst_path = "C:\dgreadiness" | ||
| dgreadiness_path_cmd = "cd ${dst_path}\dgreadiness" | ||
| set_ps_policy_cmd = 'powershell -command "Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Force"' | ||
| vbs_enable_cmd = 'powershell -command ".\DG_Readiness_Tool_v3.6.ps1 -Enable"' | ||
| vbs_disable_cmd = 'powershell -command ".\DG_Readiness_Tool_v3.6.ps1 -Disable"' | ||
| vbs_ready_cmd = 'powershell -command ".\DG_Readiness_Tool_v3.6.ps1 -Ready"' | ||
| vbs_enable_info = 'Enabling Hyper-V and IOMMU successful' | ||
| vbs_disable_info = 'Disabling Hyper-V and IOMMU successful' | ||
| vbs_ready_info = 'HVCI, Credential-Guard, and Config-CI are enabled and running' | ||
| dg_command = 'powershell -command "Get-CimInstance -ClassName Win32_DeviceGuard' | ||
| dg_command += ' -Namespace root/Microsoft/Windows/DeviceGuard"' | ||
| # WSL2 commands | ||
| wsl_enable_cmd = 'dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart' | ||
| vm_platform_cmd = 'dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart' | ||
| wsl_set_default_cmd = 'wsl --set-default-version 2' | ||
| rhel_install_cmd = 'wsl --install -d RHEL' | ||
| wsl_list_cmd = 'wsl --list --verbose' | ||
| rhel_distro_name = 'RHEL' | ||
| rhel_test_cmd = 'wsl -d RHEL -- uname -a' | ||
| # iommu setting, currently qemu only compatible with intel model | ||
| variants: | ||
| - no_iommu: | ||
| - iommu_enable: | ||
| only HostCpuVendor.intel | ||
| machine_type_extra_params = "kernel-irqchip=split" | ||
| # iommu device | ||
| intel_iommu = yes | ||
| iommu_device_iotlb = on | ||
| iommu_eim = off | ||
| iommu_intremap = on | ||
| iommu_aw_bits = 48 | ||
| # virtio device | ||
| virtio_dev_iommu_platform = on | ||
| virtio_dev_filter = '^(?:(?:virtio-)|(?:vhost-))(?!(?:user)|(?:iommu))' | ||
| # ats=on parily used with device-iotlb=on | ||
| virtio_dev_ats = on | ||
| enable_guest_iommu = yes |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,199 @@ | ||
| from virttest import data_dir, env_process, error_context | ||
|
|
||
|
|
||
| @error_context.context_aware | ||
| def run(test, params, env): | ||
| """ | ||
| Please make sure the guest installed with signed driver | ||
| Verify Secure MOR control feature using Device Guard tool in Windows guest: | ||
|
|
||
| 1) Boot up a guest. | ||
| 2) Check if Secure Boot is enable. | ||
| 3) Download DG_Readiness_Tool and copy to guest. | ||
| 4) Enable Device Guard and check the output. | ||
| 5) Reboot guest. | ||
| 6) Check the result of Device Guard. | ||
| 7) Disable Device Guard and shutdown guest. | ||
|
|
||
| :param test: QEMU test object | ||
| :param params: Dictionary with the test parameters | ||
| :param env: Dictionary with test environment. | ||
| """ | ||
|
|
||
| def set_powershell_execute_policy(): | ||
| """ | ||
| Set PowerShell execution policy using the provided session. | ||
| It is used when creating a new session. | ||
|
|
||
| :param cmd: The PowerShell command to set execution policy. | ||
| """ | ||
| error_context.context("Setting PowerShell execution policy.") | ||
| status, output = session.cmd_status_output(executionPolicy_command) | ||
| if status != 0: | ||
| test.fail("Failed to set PowerShell execution policy: %s" % output) | ||
|
|
||
| def check_secure_boot_enabled(): | ||
| """ | ||
| Checks if Secure Boot is enabled in the guest. | ||
| """ | ||
| error_context.context("Checking if Secure Boot is enabled in the guest") | ||
| output = session.cmd_output(check_cmd) | ||
| if "false" in output.lower(): | ||
| test.fail("Secure Boot is not enabled: %s" % output) | ||
|
|
||
| def copy_dg_readiness_tool(): | ||
| """ | ||
| Copies the Device Guard Readiness tool from the host to the guest VM. | ||
| """ | ||
| dgreadiness_host_path = data_dir.get_deps_dir("dgreadiness") | ||
| dst_path = params["dst_path"] | ||
| test.log.info("Copy Device Guard tool to guest.") | ||
| s, o = session.cmd_status_output("mkdir %s" % dst_path) | ||
| if s and "already exists" not in o: | ||
| test.error( | ||
| "Could not create Device Guard directory in " | ||
| "VM '%s', detail: '%s'" % (vm.name, o) | ||
| ) | ||
| vm.copy_files_to(dgreadiness_host_path, dst_path) | ||
|
|
||
| def check_vbs_ready(): | ||
| """ | ||
| Check the status of Virtualization-Based Security (VBS) using the provided | ||
| session. | ||
|
|
||
| :return: True if VBS is enabled, False otherwise. | ||
| """ | ||
| status, output = session.cmd_status_output(ready_command) | ||
| if status != 0: | ||
| test.fail("Failed to check VBS status: %s" % output) | ||
| if vbs_ready_info in output: | ||
| test.log.info("VBS is already enabled, and guest boot up successfully") | ||
| return True | ||
| else: | ||
| test.log.info( | ||
| "VBS is not enabled or the expected info was not found in the output" | ||
| ) | ||
| return False | ||
|
|
||
| def run_device_guard_tool(cmd, expect_info): | ||
| """ | ||
| Executes the Device Guard Readiness Tool command in the guest to enable | ||
| or disable Virtualization-Based Security (VBS). | ||
|
|
||
| :param cmd: The command to enable or disable VBS. | ||
| """ | ||
| error_context.context("running device guard readiness tool with %s" % cmd) | ||
| output = session.cmd_output(cmd, 360) | ||
| if expect_info not in output: | ||
| test.fail("Failed to enable VBS: %s" % output) | ||
|
|
||
| def install_wsl2_and_rhel(): | ||
| """ | ||
| Install WSL2 and start RHEL distribution in Windows VM. | ||
| This function is called after VBS verification (step 5). | ||
| """ | ||
| error_context.context("Installing WSL2 and RHEL distribution") | ||
|
|
||
| # Enable WSL feature | ||
| test.log.info("Enabling WSL feature...") | ||
| status, output = session.cmd_status_output(wsl_enable_cmd, timeout=300) | ||
| if status != 0: | ||
| test.fail("Failed to enable WSL feature: %s" % output) | ||
|
|
||
| # Enable Virtual Machine Platform | ||
| test.log.info("Enabling Virtual Machine Platform...") | ||
| status, output = session.cmd_status_output(vm_platform_cmd, timeout=300) | ||
| if status != 0: | ||
| test.fail("Failed to enable VM Platform: %s" % output) | ||
|
|
||
| # Reboot to apply WSL2 features | ||
| test.log.info("Rebooting to apply WSL2 features...") | ||
| vm.reboot(timeout=login_timeout) | ||
| new_session = vm.wait_for_serial_login(timeout=login_timeout) | ||
| set_powershell_execute_policy() | ||
| new_session.cmd(dgreadiness_path_command) | ||
|
|
||
| # Set WSL2 as default | ||
| test.log.info("Setting WSL2 as default version...") | ||
| status, output = new_session.cmd_status_output(wsl_set_default_cmd, timeout=60) | ||
| if status != 0: | ||
| test.fail("Failed to set WSL2 default: %s" % output) | ||
|
|
||
| # Install RHEL distribution | ||
| test.log.info("Installing RHEL distribution...") | ||
| status, output = new_session.cmd_status_output(rhel_install_cmd, timeout=600) | ||
| if status != 0: | ||
| test.fail("Failed to install RHEL: %s" % output) | ||
|
|
||
| # Verify WSL2 and RHEL installation | ||
| test.log.info("Verifying WSL2 and RHEL...") | ||
| status, output = new_session.cmd_status_output(wsl_list_cmd, timeout=60) | ||
| if status != 0: | ||
| test.fail("Failed to list WSL distributions: %s" % output) | ||
| if rhel_distro_name not in output: | ||
| test.fail("RHEL distribution not found: %s" % output) | ||
|
|
||
| # Test RHEL functionality | ||
| test.log.info("Testing RHEL in WSL2...") | ||
| status, output = new_session.cmd_status_output(rhel_test_cmd, timeout=120) | ||
| if status != 0: | ||
| test.fail("RHEL test failed: %s" % output) | ||
| test.log.info("WSL2 with RHEL installed and verified successfully") | ||
| return new_session | ||
|
|
||
| login_timeout = int(params.get("login_timeout", 360)) | ||
| params["ovmf_vars_filename"] = "OVMF_VARS.secboot.fd" | ||
|
|
||
| # Force the image name to use the cloned version | ||
| vm_name = params["main_vm"] | ||
| image_name = params.get("image_name", "image") | ||
| cloned_image_name = f"{image_name}_{vm_name}" | ||
| params["image_name"] = cloned_image_name | ||
|
|
||
| params["start_vm"] = "yes" | ||
| env_process.preprocess_vm(test, params, env, params["main_vm"]) | ||
| vm = env.get_vm(params["main_vm"]) | ||
| session = vm.wait_for_serial_login(timeout=login_timeout) | ||
|
|
||
| check_cmd = params["check_secure_boot_enabled_cmd"] | ||
| dgreadiness_path_command = params["dgreadiness_path_cmd"] | ||
| executionPolicy_command = params["set_ps_policy_cmd"] | ||
| enable_command = params["vbs_enable_cmd"] | ||
| disable_command = params["vbs_disable_cmd"] | ||
| ready_command = params["vbs_ready_cmd"] | ||
| vbs_ready_info = params["vbs_ready_info"] | ||
| vbs_enable_info = params["vbs_enable_info"] | ||
| vbs_disable_info = params["vbs_disable_info"] | ||
| wsl_enable_cmd = params["wsl_enable_cmd"] | ||
| vm_platform_cmd = params["vm_platform_cmd"] | ||
| wsl_set_default_cmd = params["wsl_set_default_cmd"] | ||
| rhel_install_cmd = params["rhel_install_cmd"] | ||
| wsl_list_cmd = params["wsl_list_cmd"] | ||
| rhel_distro_name = params["rhel_distro_name"] | ||
| rhel_test_cmd = params["rhel_test_cmd"] | ||
|
|
||
| try: | ||
| check_secure_boot_enabled() | ||
| copy_dg_readiness_tool() | ||
| set_powershell_execute_policy() | ||
| session.cmd(dgreadiness_path_command) | ||
| if not check_vbs_ready(): | ||
| run_device_guard_tool(enable_command, vbs_enable_info) | ||
| vm.reboot(timeout=login_timeout) | ||
| session = vm.wait_for_serial_login(timeout=login_timeout) | ||
| session.cmd(dgreadiness_path_command) | ||
| set_powershell_execute_policy() | ||
| if not check_vbs_ready(): | ||
| test.fail("VBS is not enabled after reboot.") | ||
|
|
||
| session = install_wsl2_and_rhel() | ||
| run_device_guard_tool(disable_command, vbs_disable_info) | ||
| except Exception as e: | ||
| test.fail(f"Test failed: {e}") | ||
| else: | ||
| test.log.info("Test completed successfully.") | ||
| finally: | ||
| if vm.is_alive(): | ||
| vm.destroy() | ||
| if session: | ||
| session.close() | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix PowerShell policy helper to use the active session
After the WSL reboot we create
new_session, butset_powershell_execute_policy()still dereferences the oldsessioncaptured from the outer scope. That handle is already invalid once the guest reboots, so the execution-policy command either fails outright or silently never updates the new session, breaking the rest of the workflow. Pass the live session object into the helper so that every call (including the one right after the reboot) runs against the correct connection.Also applies to: 111-114, 174-183
🤖 Prompt for AI Agents