From 8784269c715d87a9588aea43c863ebf0028a02f2 Mon Sep 17 00:00:00 2001 From: eabdullin Date: Mon, 30 Sep 2024 16:47:09 +0000 Subject: [PATCH] import CS virt-what-1.25-10.el9 --- ...arrange-lxc-test-to-avoid-use-of-cat.patch | 2 +- ...ker-and-podman-tests-up-add-comments.patch | 2 +- ...location-of-test-file-proc-1-environ.patch | 2 +- SOURCES/0004-Detect-OCI-containers.patch | 2 +- ...support-for-Alibaba-cloud-on-aarch64.patch | 2 +- ...atch-Nutanix-based-baremetal-systems.patch | 2 +- ...007-Add-support-for-CRI-O-containers.patch | 2 +- .../0008-Fix-support-for-Hyper-V-on-Arm.patch | 494 ++++++++++++ ...0009-Introduce-virt-what-cvm-program.patch | 714 ++++++++++++++++++ ...eference-to-virt-what-cvm-1-to-virt-.patch | 25 + ...t-cvm-check-if-hypervisor-bit-is-set.patch | 77 ++ ...pport-alternative-cpuid-leaf-orderin.patch | 59 ++ ...obe-for-SNP-HCL-on-HyperV-Azure-via-.patch | 117 +++ ...op-TPM-logic-for-detecting-SNP-on-Hy.patch | 258 +++++++ ...-rename-azure-hcl-fact-to-hyperv-hcl.patch | 53 ++ ...-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch | 26 + ...-Fix-CVM-detection-on-Azure-with-TDX.patch | 98 +++ ...detecting-protected-virtualization-o.patch | 66 ++ ...d-Fix-man-page-typo-s390x-protvirt-s.patch | 29 + SOURCES/copy-patches.sh | 2 +- SPECS/virt-what.spec | 29 +- 21 files changed, 2051 insertions(+), 10 deletions(-) create mode 100644 SOURCES/0008-Fix-support-for-Hyper-V-on-Arm.patch create mode 100644 SOURCES/0009-Introduce-virt-what-cvm-program.patch create mode 100644 SOURCES/0010-docs-Add-cross-reference-to-virt-what-cvm-1-to-virt-.patch create mode 100644 SOURCES/0011-virt-what-cvm-check-if-hypervisor-bit-is-set.patch create mode 100644 SOURCES/0012-virt-what-cvm-support-alternative-cpuid-leaf-orderin.patch create mode 100644 SOURCES/0013-virt-what-cvm-probe-for-SNP-HCL-on-HyperV-Azure-via-.patch create mode 100644 SOURCES/0014-virt-what-cvm-drop-TPM-logic-for-detecting-SNP-on-Hy.patch create mode 100644 SOURCES/0015-virt-what-cvm-rename-azure-hcl-fact-to-hyperv-hcl.patch create mode 100644 SOURCES/0016-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch create mode 100644 SOURCES/0017-Fix-CVM-detection-on-Azure-with-TDX.patch create mode 100644 SOURCES/0018-Add-support-for-detecting-protected-virtualization-o.patch create mode 100644 SOURCES/0019-virt-what-cvm.pod-Fix-man-page-typo-s390x-protvirt-s.patch diff --git a/SOURCES/0001-Rearrange-lxc-test-to-avoid-use-of-cat.patch b/SOURCES/0001-Rearrange-lxc-test-to-avoid-use-of-cat.patch index a70ad4e..6270367 100644 --- a/SOURCES/0001-Rearrange-lxc-test-to-avoid-use-of-cat.patch +++ b/SOURCES/0001-Rearrange-lxc-test-to-avoid-use-of-cat.patch @@ -23,5 +23,5 @@ index d090898e5..170bc24ab 100644 fi -- -2.39.1 +2.43.0 diff --git a/SOURCES/0002-Move-docker-and-podman-tests-up-add-comments.patch b/SOURCES/0002-Move-docker-and-podman-tests-up-add-comments.patch index 68ac80e..2f645c4 100644 --- a/SOURCES/0002-Move-docker-and-podman-tests-up-add-comments.patch +++ b/SOURCES/0002-Move-docker-and-podman-tests-up-add-comments.patch @@ -79,5 +79,5 @@ index 170bc24ab..c6e4a1e00 100644 # example /proc/cpuinfo line indicating 'not baremetal' -- -2.39.1 +2.43.0 diff --git a/SOURCES/0003-podman-Fix-location-of-test-file-proc-1-environ.patch b/SOURCES/0003-podman-Fix-location-of-test-file-proc-1-environ.patch index 8f408e6..941278c 100644 --- a/SOURCES/0003-podman-Fix-location-of-test-file-proc-1-environ.patch +++ b/SOURCES/0003-podman-Fix-location-of-test-file-proc-1-environ.patch @@ -32,5 +32,5 @@ similarity index 100% rename from tests/podman/1/environ rename to tests/podman/proc/1/environ -- -2.39.1 +2.43.0 diff --git a/SOURCES/0004-Detect-OCI-containers.patch b/SOURCES/0004-Detect-OCI-containers.patch index 793894a..63b9c67 100644 --- a/SOURCES/0004-Detect-OCI-containers.patch +++ b/SOURCES/0004-Detect-OCI-containers.patch @@ -884,5 +884,5 @@ index 2c346bded..9dbc079f9 100644 Status: contributed by Jordan Webb -- -2.39.1 +2.43.0 diff --git a/SOURCES/0005-Add-support-for-Alibaba-cloud-on-aarch64.patch b/SOURCES/0005-Add-support-for-Alibaba-cloud-on-aarch64.patch index f054f72..cebeee2 100644 --- a/SOURCES/0005-Add-support-for-Alibaba-cloud-on-aarch64.patch +++ b/SOURCES/0005-Add-support-for-Alibaba-cloud-on-aarch64.patch @@ -367,5 +367,5 @@ index 102e23f67..fbf8c54c5 100644 # The test for KVM above failed, so now we know we're # not using KVM acceleration. -- -2.39.1 +2.43.0 diff --git a/SOURCES/0006-nutanix-Don-t-match-Nutanix-based-baremetal-systems.patch b/SOURCES/0006-nutanix-Don-t-match-Nutanix-based-baremetal-systems.patch index c0146f7..5d2f80c 100644 --- a/SOURCES/0006-nutanix-Don-t-match-Nutanix-based-baremetal-systems.patch +++ b/SOURCES/0006-nutanix-Don-t-match-Nutanix-based-baremetal-systems.patch @@ -34,5 +34,5 @@ index fbf8c54c5..e310f339b 100644 fi -- -2.39.1 +2.43.0 diff --git a/SOURCES/0007-Add-support-for-CRI-O-containers.patch b/SOURCES/0007-Add-support-for-CRI-O-containers.patch index 8a8c1e8..ecb3373 100644 --- a/SOURCES/0007-Add-support-for-CRI-O-containers.patch +++ b/SOURCES/0007-Add-support-for-CRI-O-containers.patch @@ -1548,5 +1548,5 @@ index 9dbc079f9..45dd7c933 100644 This is a Docker container. -- -2.39.1 +2.43.0 diff --git a/SOURCES/0008-Fix-support-for-Hyper-V-on-Arm.patch b/SOURCES/0008-Fix-support-for-Hyper-V-on-Arm.patch new file mode 100644 index 0000000..439327b --- /dev/null +++ b/SOURCES/0008-Fix-support-for-Hyper-V-on-Arm.patch @@ -0,0 +1,494 @@ +From 128d73c47ef90ca871966a5417962836f9f359f1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 2 Jul 2024 08:45:10 +0000 +Subject: [PATCH] Fix support for Hyper-V on Arm + +This architecture lacks CPUID so we must fall back to looking +at DMI data instead. + +Reported-by: Yuxin Sun +Thanks: Dan Berrange +Fixes: https://issues.redhat.com/browse/RHEL-45834 +(cherry picked from commit 49a17ec8438d01280750d52ae661c8c5c9fe9d07) +--- + configure.ac | 2 + + tests/hyperv-arm/Makefile.am | 28 +++ + tests/hyperv-arm/proc/cpuinfo | 18 ++ + tests/hyperv-arm/proc/self/status | 57 +++++ + tests/hyperv-arm/sbin/dmidecode | 221 +++++++++++++++++++ + tests/hyperv-arm/sbin/uname | 2 + + tests/hyperv-arm/sbin/virt-what-cpuid-helper | 2 + + tests/hyperv-arm/test.sh | 32 +++ + virt-what.in | 16 +- + 9 files changed, 374 insertions(+), 4 deletions(-) + create mode 100644 tests/hyperv-arm/Makefile.am + create mode 100644 tests/hyperv-arm/proc/cpuinfo + create mode 100644 tests/hyperv-arm/proc/self/status + create mode 100755 tests/hyperv-arm/sbin/dmidecode + create mode 100755 tests/hyperv-arm/sbin/uname + create mode 100755 tests/hyperv-arm/sbin/virt-what-cpuid-helper + create mode 100755 tests/hyperv-arm/test.sh + +diff --git a/configure.ac b/configure.ac +index 632e25e91..4dd2c9731 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -48,6 +48,7 @@ tests="\ + esx4.1 \ + google-cloud \ + hyperv \ ++ hyperv-arm \ + illumos-lx \ + kvm \ + kvm-explicit-cpu \ +@@ -99,6 +100,7 @@ AC_CONFIG_FILES([Makefile + tests/esx4.1/Makefile + tests/google-cloud/Makefile + tests/hyperv/Makefile ++ tests/hyperv-arm/Makefile + tests/illumos-lx/Makefile + tests/kvm/Makefile + tests/kvm-explicit-cpu/Makefile +diff --git a/tests/hyperv-arm/Makefile.am b/tests/hyperv-arm/Makefile.am +new file mode 100644 +index 000000000..b748df8bc +--- /dev/null ++++ b/tests/hyperv-arm/Makefile.am +@@ -0,0 +1,28 @@ ++# Makefile for virt-what ++# Copyright (C) 2008-2011 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++CLEANFILES = *~ ++ ++TESTS = test.sh ++ ++EXTRA_DIST = \ ++ test.sh \ ++ proc/cpuinfo \ ++ proc/self/status \ ++ sbin/dmidecode \ ++ sbin/uname \ ++ sbin/virt-what-cpuid-helper +diff --git a/tests/hyperv-arm/proc/cpuinfo b/tests/hyperv-arm/proc/cpuinfo +new file mode 100644 +index 000000000..c492a0024 +--- /dev/null ++++ b/tests/hyperv-arm/proc/cpuinfo +@@ -0,0 +1,18 @@ ++processor : 0 ++BogoMIPS : 50.00 ++Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ++CPU implementer : 0x41 ++CPU architecture: 8 ++CPU variant : 0x3 ++CPU part : 0xd0c ++CPU revision : 1 ++ ++processor : 1 ++BogoMIPS : 50.00 ++Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ++CPU implementer : 0x41 ++CPU architecture: 8 ++CPU variant : 0x3 ++CPU part : 0xd0c ++CPU revision : 1 ++ +diff --git a/tests/hyperv-arm/proc/self/status b/tests/hyperv-arm/proc/self/status +new file mode 100644 +index 000000000..129e9c2aa +--- /dev/null ++++ b/tests/hyperv-arm/proc/self/status +@@ -0,0 +1,57 @@ ++Name: cat ++Umask: 0022 ++State: R (running) ++Tgid: 17916 ++Ngid: 0 ++Pid: 17916 ++PPid: 5880 ++TracerPid: 0 ++Uid: 1000 1000 1000 1000 ++Gid: 1000 1000 1000 1000 ++FDSize: 256 ++Groups: 4 190 1000 ++NStgid: 17916 ++NSpid: 17916 ++NSpgid: 17916 ++NSsid: 5880 ++VmPeak: 5284 kB ++VmSize: 5284 kB ++VmLck: 0 kB ++VmPin: 0 kB ++VmHWM: 772 kB ++VmRSS: 772 kB ++RssAnon: 80 kB ++RssFile: 692 kB ++RssShmem: 0 kB ++VmData: 344 kB ++VmStk: 132 kB ++VmExe: 24 kB ++VmLib: 1736 kB ++VmPTE: 48 kB ++VmSwap: 0 kB ++HugetlbPages: 0 kB ++CoreDumping: 0 ++THP_enabled: 1 ++Threads: 1 ++SigQ: 0/30549 ++SigPnd: 0000000000000000 ++ShdPnd: 0000000000000000 ++SigBlk: 0000000000000000 ++SigIgn: 0000000000000000 ++SigCgt: 0000000000000000 ++CapInh: 0000000000000000 ++CapPrm: 0000000000000000 ++CapEff: 0000000000000000 ++CapBnd: 000001ffffffffff ++CapAmb: 0000000000000000 ++NoNewPrivs: 0 ++Seccomp: 0 ++Seccomp_filters: 0 ++Speculation_Store_Bypass: not vulnerable ++SpeculationIndirectBranch: unknown ++Cpus_allowed: 3 ++Cpus_allowed_list: 0-1 ++Mems_allowed: 00000000,00000001 ++Mems_allowed_list: 0 ++voluntary_ctxt_switches: 0 ++nonvoluntary_ctxt_switches: 0 +diff --git a/tests/hyperv-arm/sbin/dmidecode b/tests/hyperv-arm/sbin/dmidecode +new file mode 100755 +index 000000000..38ac3feac +--- /dev/null ++++ b/tests/hyperv-arm/sbin/dmidecode +@@ -0,0 +1,221 @@ ++#!/bin/sh - ++cat <<'EOF' ++# dmidecode 3.3 ++Getting SMBIOS data from sysfs. ++SMBIOS 3.1.0 present. ++Table at 0x3FD63000. ++ ++Handle 0x0000, DMI type 0, 26 bytes ++BIOS Information ++ Vendor: Microsoft Corporation ++ Version: Hyper-V UEFI Release v4.1 ++ Release Date: 11/28/2023 ++ ROM Size: 64 kB ++ Characteristics: ++ BIOS characteristics not supported ++ ACPI is supported ++ Targeted content distribution is supported ++ UEFI is supported ++ System is a virtual machine ++ BIOS Revision: 4.1 ++ ++Handle 0x0001, DMI type 1, 27 bytes ++System Information ++ Manufacturer: Microsoft Corporation ++ Product Name: Virtual Machine ++ Version: Hyper-V UEFI Release v4.1 ++ Serial Number: 0000-0011-3798-4833-3781-8467-28 ++ UUID: 9ded57c4-3ce3-4ac8-aaaf-2c4ccf6e7a59 ++ Wake-up Type: Power Switch ++ SKU Number: None ++ Family: Virtual Machine ++ ++Handle 0x0002, DMI type 3, 24 bytes ++Chassis Information ++ Manufacturer: Microsoft Corporation ++ Type: Desktop ++ Lock: Not Present ++ Version: Hyper-V UEFI Release v4.1 ++ Serial Number: 6708-6940-4856-4751-7507-5546-20 ++ Asset Tag: 7783-7084-3265-9085-8269-3286-77 ++ Boot-up State: Safe ++ Power Supply State: Safe ++ Thermal State: Safe ++ Security Status: Unknown ++ OEM Information: 0x00000000 ++ Height: Unspecified ++ Number Of Power Cords: Unspecified ++ Contained Elements: 0 ++ SKU Number: Virtual Machine ++ ++Handle 0x0003, DMI type 2, 17 bytes ++Base Board Information ++ Manufacturer: Microsoft Corporation ++ Product Name: Virtual Machine ++ Version: Hyper-V UEFI Release v4.1 ++ Serial Number: 0000-0012-2990-9781-5781-3745-53 ++ Asset Tag: None ++ Features: ++ Board is a hosting board ++ Location In Chassis: Virtual Machine ++ Chassis Handle: 0x0002 ++ Type: Motherboard ++ Contained Object Handles: 0 ++ ++Handle 0x0004, DMI type 4, 48 bytes ++Processor Information ++ Socket Designation: None ++ Type: Central Processor ++ Family: ARMv8 ++ Manufacturer: Ampere(R) ++ ID: 00 00 00 00 00 00 00 00 ++ Version: Ampere(R) Altra(R) Processor ++ Voltage: 1.0 V ++ External Clock: 1650 MHz ++ Max Speed: 3000 MHz ++ Current Speed: 3000 MHz ++ Status: Populated, Enabled ++ Upgrade: None ++ L1 Cache Handle: Not Provided ++ L2 Cache Handle: Not Provided ++ L3 Cache Handle: Not Provided ++ Serial Number: None ++ Asset Tag: None ++ Part Number: None ++ Core Count: 2 ++ Core Enabled: 2 ++ Thread Count: 1 ++ Characteristics: ++ 64-bit capable ++ Multi-Core ++ Power/Performance Control ++ 128-bit Capable ++ Arm64 SoC ID ++ ++Handle 0x0005, DMI type 11, 5 bytes ++OEM Strings ++ String 1: [MS_VM_CERT/SHA1/9b80ca0d5dd061ec9da4e494f4c3fd1196270c22] ++ String 2: 00000000000000000000000000000000 ++ String 3: To be filled by OEM ++ ++Handle 0x0006, DMI type 16, 23 bytes ++Physical Memory Array ++ Location: System Board Or Motherboard ++ Use: System Memory ++ Error Correction Type: None ++ Maximum Capacity: 0 bytes ++ Error Information Handle: Not Provided ++ Number Of Devices: 2 ++ ++Handle 0x0007, DMI type 17, 92 bytes ++Memory Device ++ Array Handle: 0x0006 ++ Error Information Handle: Not Provided ++ Total Width: Unknown ++ Data Width: Unknown ++ Size: 1 GB ++ Form Factor: Unknown ++ Set: None ++ Locator: M0001 ++ Bank Locator: None ++ Type: Unknown ++ Type Detail: Unknown ++ Speed: Unknown ++ Manufacturer: Microsoft Corporation ++ Serial Number: None ++ Asset Tag: None ++ Part Number: None ++ Rank: Unknown ++ Configured Memory Speed: Unknown ++ Minimum Voltage: Unknown ++ Maximum Voltage: Unknown ++ Configured Voltage: Unknown ++ Memory Technology: ++ Memory Operating Mode Capability: None ++ Firmware Version: Not Specified ++ Module Manufacturer ID: Unknown ++ Module Product ID: Unknown ++ Memory Subsystem Controller Manufacturer ID: Unknown ++ Memory Subsystem Controller Product ID: Unknown ++ Non-Volatile Size: None ++ Volatile Size: None ++ Cache Size: None ++ Logical Size: None ++ ++Handle 0x0008, DMI type 19, 31 bytes ++Memory Array Mapped Address ++ Starting Address: 0x00000000000 ++ Ending Address: 0x000400003FF ++ Range Size: 1 GB ++ Physical Array Handle: 0x0006 ++ Partition Width: 0 ++ ++Handle 0x0009, DMI type 20, 35 bytes ++Memory Device Mapped Address ++ Starting Address: 0x00000000000 ++ Ending Address: 0x000400003FF ++ Range Size: 1 GB ++ Physical Device Handle: 0x0007 ++ Memory Array Mapped Address Handle: 0x0008 ++ Partition Row Position: Unknown ++ ++Handle 0x000A, DMI type 17, 92 bytes ++Memory Device ++ Array Handle: 0x0006 ++ Error Information Handle: Not Provided ++ Total Width: Unknown ++ Data Width: Unknown ++ Size: 7 GB ++ Form Factor: Unknown ++ Set: None ++ Locator: M0002 ++ Bank Locator: None ++ Type: Unknown ++ Type Detail: Unknown ++ Speed: Unknown ++ Manufacturer: Microsoft Corporation ++ Serial Number: None ++ Asset Tag: None ++ Part Number: None ++ Rank: Unknown ++ Configured Memory Speed: Unknown ++ Minimum Voltage: Unknown ++ Maximum Voltage: Unknown ++ Configured Voltage: Unknown ++ Memory Technology: ++ Memory Operating Mode Capability: None ++ Firmware Version: Not Specified ++ Module Manufacturer ID: Unknown ++ Module Product ID: Unknown ++ Memory Subsystem Controller Manufacturer ID: Unknown ++ Memory Subsystem Controller Product ID: Unknown ++ Non-Volatile Size: None ++ Volatile Size: None ++ Cache Size: None ++ Logical Size: None ++ ++Handle 0x000B, DMI type 19, 31 bytes ++Memory Array Mapped Address ++ Starting Address: 0x00100000000 ++ Ending Address: 0x002C00003FF ++ Range Size: 7 GB ++ Physical Array Handle: 0x0006 ++ Partition Width: 0 ++ ++Handle 0x000C, DMI type 20, 35 bytes ++Memory Device Mapped Address ++ Starting Address: 0x00100000000 ++ Ending Address: 0x002C00003FF ++ Range Size: 7 GB ++ Physical Device Handle: 0x000A ++ Memory Array Mapped Address Handle: 0x000B ++ Partition Row Position: Unknown ++ ++Handle 0x000D, DMI type 32, 11 bytes ++System Boot Information ++ Status: No errors detected ++ ++Handle 0xFEFF, DMI type 127, 4 bytes ++End Of Table ++ ++EOF +diff --git a/tests/hyperv-arm/sbin/uname b/tests/hyperv-arm/sbin/uname +new file mode 100755 +index 000000000..bd33a2d73 +--- /dev/null ++++ b/tests/hyperv-arm/sbin/uname +@@ -0,0 +1,2 @@ ++#!/bin/sh - ++echo aarch64 +diff --git a/tests/hyperv-arm/sbin/virt-what-cpuid-helper b/tests/hyperv-arm/sbin/virt-what-cpuid-helper +new file mode 100755 +index 000000000..77a669235 +--- /dev/null ++++ b/tests/hyperv-arm/sbin/virt-what-cpuid-helper +@@ -0,0 +1,2 @@ ++#!/bin/sh - ++# nothing +diff --git a/tests/hyperv-arm/test.sh b/tests/hyperv-arm/test.sh +new file mode 100755 +index 000000000..50fca7431 +--- /dev/null ++++ b/tests/hyperv-arm/test.sh +@@ -0,0 +1,32 @@ ++# Test for Microsoft HyperV. ++# Copyright (C) 2008-2024 Red Hat Inc. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 2 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++output="$(PATH=../..:$PATH virt-what --test-root=. 2>&1)" ++expected="hyperv" ++ ++if [ "$output" != "$expected" ]; then ++ echo "$0: test failed because output did not match expected" ++ echo "Expected output was:" ++ echo "----------------------------------------" ++ echo "$expected" ++ echo "----------------------------------------" ++ echo "But the actual output of the program was:" ++ echo "----------------------------------------" ++ echo "$output" ++ echo "----------------------------------------" ++ exit 1 ++fi +diff --git a/virt-what.in b/virt-what.in +index 5c5b54b92..77b385f91 100644 +--- a/virt-what.in ++++ b/virt-what.in +@@ -1,6 +1,6 @@ + #!/bin/sh - + # @configure_input@ +-# Copyright (C) 2008-2022 Red Hat Inc. ++# Copyright (C) 2008-2024 Red Hat Inc. + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by +@@ -136,14 +136,22 @@ fi + # http://blogs.msdn.com/b/sqlosteam/archive/2010/10/30/is-this-real-the-metaphysics-of-hardware-virtualization.aspx + if [ "$cpuid" = "Microsoft Hv" ]; then + echo hyperv ++# Hyper-V on ARM doesn't have CPUID. Use the information in dmidecode ++# instead. Note this is similar to VirtualPC below. ++elif echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation' && ++ echo "$dmi" | grep -q 'Product Name: Virtual Machine' && ++ echo "$dmi" | grep -q 'Version: Hyper-V'; then ++ echo hyperv + fi + + # Check for VirtualPC. +-# The negative check for cpuid is to distinguish this from Hyper-V +-# which also has the same manufacturer string in the SM-BIOS data. ++# The negative check for cpuid & Hyper-V is to distinguish this from ++# Hyper-V above which also has the same manufacturer string in the ++# SM-BIOS data. + if [ "$cpuid" != "Microsoft Hv" ] && + echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation' && +- echo "$dmi" | grep -q 'Product Name: Virtual Machine'; then ++ echo "$dmi" | grep -q 'Product Name: Virtual Machine' && ++ ! echo "$dmi" | grep -q 'Version: Hyper-V'; then + echo virtualpc + fi + +-- +2.43.0 + diff --git a/SOURCES/0009-Introduce-virt-what-cvm-program.patch b/SOURCES/0009-Introduce-virt-what-cvm-program.patch new file mode 100644 index 0000000..04a089b --- /dev/null +++ b/SOURCES/0009-Introduce-virt-what-cvm-program.patch @@ -0,0 +1,714 @@ +From 772dfd3a966d766d4566fd048f8b0178f7f827e5 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 26 May 2023 12:39:03 +0100 +Subject: [PATCH] Introduce 'virt-what-cvm' program +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The 'virt-what' program prints facts that reflect the hypervisor that +the guest is running under. + +The new complementary 'virt-what-cvm' program prints facts that reflect +the confidential virtualization technology the guest is running under, +if any. + +It is kept as a separate tool, rather than incorporating the facts into +'virt-what' output because it is considering a different aspect of the +virtualization. Furthermore there are specific security concerns around +the usage of facts reported by 'virt-what-cvm'. + +The tool has been tested in a number of environments + + * Azure confidential guest with AMD SEV-SNP (GA) + * Azure confidential guest with Intel TDX (technology preview) + * Fedora 37 QEMU/KVM guest with AMD SEV (GA) + * Fedora 37 QEMU/KVM guest with AMD SEV-ES (GA) + * Fedora 38 QEMU/KVM guest with AMD SEV-SNP + SVSM (devel snapshot) + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 22e33361e980ddefe08e2c68bf145943af8375f9) +--- + .gitignore | 3 + + Makefile.am | 12 +- + configure.ac | 3 + + virt-what-cvm.c | 404 ++++++++++++++++++++++++++++++++++++++++++++++ + virt-what-cvm.pod | 195 ++++++++++++++++++++++ + 5 files changed, 613 insertions(+), 4 deletions(-) + create mode 100644 virt-what-cvm.c + create mode 100644 virt-what-cvm.pod + +diff --git a/.gitignore b/.gitignore +index 4833fd6be..ba897a162 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -26,5 +26,8 @@ Makefile.in + /test-driver + /virt-what + /virt-what-cpuid-helper ++/virt-what-cvm ++/virt-what-cvm.1 ++/virt-what-cvm.txt + /virt-what.1 + /virt-what.txt +diff --git a/Makefile.am b/Makefile.am +index 543513204..2050bef8d 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -24,20 +24,24 @@ EXTRA_DIST = .gitignore virt-what.in virt-what.pod + SUBDIRS = . tests + + sbin_SCRIPTS = virt-what ++sbin_PROGRAMS = virt-what-cvm + libexec_PROGRAMS = virt-what-cpuid-helper + if HOST_CPU_IA64 + libexec_PROGRAMS += virt-what-ia64-xen-rdtsc-test + endif + ++virt_what_cvm_LDADD = $(TPM2_TSS_LIBS) ++virt_what_cvm_CFLAGS = $(TPM2_TSS_CFLAGS) ++ + if HAVE_POD2MAN + +-CLEANFILES += virt-what.1 virt-what.txt +-man_MANS = virt-what.1 ++CLEANFILES += virt-what.1 virt-what-cvm.1 virt-what.txt virt-what-cvm.txt ++man_MANS = virt-what.1 virt-what-cvm.1 + +-virt-what.1: virt-what.pod ++%.1: %.pod + pod2man -c "Virtualization Support" --release "$(PACKAGE)-$(VERSION)" \ + $? > $@ +-virt-what.txt: virt-what.pod ++%.txt: %.pod + pod2text $? > $@ + + endif +diff --git a/configure.ac b/configure.ac +index 4dd2c9731..b1dadd64d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -32,6 +32,9 @@ dnl Architecture we are compiling for. + AC_CANONICAL_HOST + AM_CONDITIONAL([HOST_CPU_IA64], [ test "x$host_cpu" = "xia64" ]) + ++PKG_HAVE_DEFINE_WITH_MODULES(TPM2_TSS, tss2-esys, [tpm2-tss package]) ++ ++ + dnl List of tests. + tests="\ + alibaba-cloud-arm \ +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +new file mode 100644 +index 000000000..407efb492 +--- /dev/null ++++ b/virt-what-cvm.c +@@ -0,0 +1,404 @@ ++/* virt-what-cvm-helper: Are we running inside confidential VM ++ * Copyright (C) 2023 Red Hat Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef HAVE_TPM2_TSS ++#include ++#include ++#endif ++ ++static bool dodebug = false; ++ ++#define debug(...) do { if (dodebug) fprintf(stderr, __VA_ARGS__); } while(0) ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: E4.1 - Maximum Extended Function Number and Vendor String ++ * https://www.amd.com/system/files/TechDocs/24594.pdf ++ */ ++#define CPUID_GET_HIGHEST_FUNCTION 0x80000000 ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: E4.17 - Encrypted Memory Capabilities ++ * https://www.amd.com/system/files/TechDocs/24594.pdf ++ */ ++#define CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES 0x8000001f ++ ++/* ++ * AMD64 Architecture Programmer’s Manual Volume 3: ++ * General-Purpose and System Instructions. ++ * Chapter: 15.34.10 - SEV_STATUS MSR ++ * https://www.amd.com/system/files/TechDocs/24593.pdf ++ */ ++#define MSR_AMD64_SEV 0xc0010131 ++ ++/* ++ * Intel® TDX Module v1.5 Base Architecture Specification ++ * Chapter: 11.2 ++ * https://www.intel.com/content/www/us/en/content-details/733575/intel-tdx-module-v1-5-base-architecture-specification.html ++ */ ++ ++#define CPUID_INTEL_TDX_ENUMERATION 0x21 ++ ++ ++#define CPUID_SIG_AMD "AuthenticAMD" ++#define CPUID_SIG_INTEL "GenuineIntel" ++#define CPUID_SIG_INTEL_TDX "IntelTDX " ++ ++/* ++ * This TPM NV data format is not explicitly documented anywhere, ++ * but the header definition is present in code at: ++ * ++ * https://github.com/kinvolk/azure-cvm-tooling/blob/main/az-snp-vtpm/src/hcl.rs ++ */ ++#define TPM_AZURE_HCLA_REPORT_INDEX 0x01400001 ++ ++struct TPMAzureHCLAHeader { ++ uint32_t signature; ++ uint32_t version; ++ uint32_t report_len; ++ uint32_t report_type; ++ uint32_t unknown[4]; ++}; ++ ++/* The bytes for "HCLA" */ ++#define TPM_AZURE_HCLA_SIGNATURE 0x414C4348 ++#define TPM_AZURE_HCLA_VERSION 0x1 ++#define TPM_AZURE_HCLA_REPORT_TYPE_SNP 0x2 ++ ++#if defined(__x86_64__) ++ ++#ifdef HAVE_TPM2_TSS ++static char * ++tpm_nvread(uint32_t nvindex, size_t *retlen) ++{ ++ TSS2_RC rc; ++ ESYS_CONTEXT *ctx = NULL; ++ ESYS_TR primary = ESYS_TR_NONE; ++ ESYS_TR session = ESYS_TR_NONE; ++ ESYS_TR nvobj = ESYS_TR_NONE; ++ TPM2B_NV_PUBLIC *pubData = NULL; ++ TPMT_SYM_DEF sym = { ++ .algorithm = TPM2_ALG_AES, ++ .keyBits = { .aes = 128 }, ++ .mode = { .aes = TPM2_ALG_CFB } ++ }; ++ char *ret; ++ size_t retwant; ++ ++ rc = Esys_Initialize(&ctx, NULL, NULL); ++ if (rc != TSS2_RC_SUCCESS) ++ return NULL; ++ ++ rc = Esys_Startup(ctx, TPM2_SU_CLEAR); ++ debug("tpm startup %d\n", rc); ++ if (rc != TSS2_RC_SUCCESS) ++ goto error; ++ ++ rc = Esys_StartAuthSession(ctx, ESYS_TR_NONE, ESYS_TR_NONE, ++ ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, ++ NULL, 0, ++ &sym, TPM2_ALG_SHA256, &session); ++ debug("tpm auth session %d\n", rc); ++ if (rc != TSS2_RC_SUCCESS) ++ goto error; ++ ++ rc = Esys_TR_FromTPMPublic(ctx, nvindex, ESYS_TR_NONE, ++ ESYS_TR_NONE, ESYS_TR_NONE, &nvobj); ++ debug("tpm from public %d\n", rc); ++ if (rc != TSS2_RC_SUCCESS) ++ goto error; ++ ++ rc = Esys_NV_ReadPublic(ctx, nvobj, ESYS_TR_NONE, ++ ESYS_TR_NONE, ESYS_TR_NONE, ++ &pubData, NULL); ++ debug("tpm read public %d\n", rc); ++ if (rc != TPM2_RC_SUCCESS) ++ goto error; ++ ++ retwant = pubData->nvPublic.dataSize; ++ free(pubData); ++ *retlen = 0; ++ ret = malloc(retwant); ++ assert(ret); ++ while (*retlen < retwant) { ++ size_t want = retwant - *retlen; ++ TPM2B_MAX_NV_BUFFER *data = NULL; ++ if (want > 1024) ++ want = 1024; ++ rc = Esys_NV_Read(ctx, ESYS_TR_RH_OWNER, nvobj, session, ESYS_TR_NONE, ESYS_TR_NONE, ++ want, *retlen, &data); ++ debug("tpm nv read %d\n", rc); ++ if (rc != TPM2_RC_SUCCESS) { ++ free(ret); ++ goto error; ++ } ++ ++ memcpy(ret + *retlen, data->buffer, data->size); ++ *retlen += data->size; ++ free(data); ++ } ++ ++ return ret; ++ ++ error: ++ if (nvobj != ESYS_TR_NONE) ++ Esys_FlushContext(ctx, nvobj); ++ if (session != ESYS_TR_NONE) ++ Esys_FlushContext(ctx, session); ++ if (primary != ESYS_TR_NONE) ++ Esys_FlushContext(ctx, primary); ++ Esys_Finalize(&ctx); ++ *retlen = 0; ++ return NULL; ++} ++#else /* ! HAVE_TPM2_TSS */ ++static char * ++tpm_nvread(uint32_t nvindex, size_t *retlen) ++{ ++ return NULL; ++} ++#endif /* ! HAVE_TPM2_TSS */ ++ ++/* Copied from the Linux kernel definition in ++ * arch/x86/include/asm/processor.h ++ */ ++static inline void ++cpuid (uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) ++{ ++ debug("CPUID func %x %x\n", *eax, *ecx); ++ asm volatile ("cpuid" ++ : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) ++ : "0" (*eax), "2" (*ecx) ++ : "memory"); ++ debug("CPUID result %x %x %x %x\n", *eax, *ebx, *ecx, *edx); ++} ++ ++ ++static uint32_t ++cpuid_leaf (uint32_t eax, char *sig) ++{ ++ uint32_t *sig32 = (uint32_t *) sig; ++ ++ cpuid (&eax, &sig32[0], &sig32[2], &sig32[1]); ++ sig[12] = 0; /* \0-terminate the string to make string comparison possible */ ++ debug("CPUID sig %s\n", sig); ++ return eax; ++} ++ ++#define MSR_DEVICE "/dev/cpu/0/msr" ++ ++static uint64_t ++msr (off_t index) ++{ ++ uint64_t ret; ++ int fd = open (MSR_DEVICE, O_RDONLY); ++ if (fd < 0) { ++ debug ("Cannot open MSR device %s", MSR_DEVICE); ++ return 0; ++ } ++ ++ if (pread (fd, &ret, sizeof(ret), index) != sizeof(ret)) ++ ret = 0; ++ ++ close (fd); ++ ++ debug ("MSR %llx result %llx\n", (unsigned long long)index, ++ (unsigned long long)ret); ++ return ret; ++} ++ ++bool ++cpu_sig_amd_azure (void) ++{ ++ size_t datalen = 0; ++ char *data = tpm_nvread(TPM_AZURE_HCLA_REPORT_INDEX, &datalen); ++ struct TPMAzureHCLAHeader *header = (struct TPMAzureHCLAHeader *)data; ++ bool ret; ++ ++ if (!data) ++ return false; ++ ++ if (datalen < sizeof(struct TPMAzureHCLAHeader)) { ++ debug ("TPM data len is too small to be an Azure HCLA report"); ++ return false; ++ } ++ ++ debug ("Azure TPM HCLA report header sig %x ver %x type %x\n", ++ header->signature, header->version, header->report_type); ++ ++ ret = (header->signature == TPM_AZURE_HCLA_SIGNATURE && ++ header->version == TPM_AZURE_HCLA_VERSION && ++ header->report_type == TPM_AZURE_HCLA_REPORT_TYPE_SNP); ++ debug ("Azure TPM HCLA report present ? %d\n", ret); ++ ++ free(data); ++ return ret; ++} ++ ++static void ++cpu_sig_amd (void) ++{ ++ uint32_t eax, ebx, ecx, edx; ++ uint64_t msrval; ++ ++ eax = CPUID_GET_HIGHEST_FUNCTION; ++ ebx = ecx = edx = 0; ++ ++ cpuid (&eax, &ebx, &ecx, &edx); ++ ++ if (eax < CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES) ++ return; ++ ++ eax = CPUID_AMD_GET_ENCRYPTED_MEMORY_CAPABILITIES; ++ ebx = ecx = edx = 0; ++ ++ cpuid (&eax, &ebx, &ecx, &edx); ++ ++ /* bit 1 == CPU supports SEV feature ++ * ++ * Note, Azure blocks this CPUID leaf from its SEV-SNP ++ * guests, so we must fallback to probing the TPM which ++ * exposes a SEV-SNP attestation report as evidence. ++ */ ++ if (!(eax & (1 << 1))) { ++ debug ("No sev in CPUID, try azure TPM NV\n"); ++ ++ if (cpu_sig_amd_azure()) { ++ puts ("amd-sev-snp"); ++ puts ("azure-hcl"); ++ } else { ++ debug("No azure TPM NV\n"); ++ } ++ return; ++ } ++ ++ msrval = msr (MSR_AMD64_SEV); ++ ++ /* Test reverse order, since the SEV-SNP bit implies ++ * the SEV-ES bit, which implies the SEV bit */ ++ if (msrval & (1 << 2)) { ++ puts ("amd-sev-snp"); ++ } else if (msrval & (1 << 1)) { ++ puts ("amd-sev-es"); ++ } else if (msrval & (1 << 0)) { ++ puts ("amd-sev"); ++ } ++} ++ ++static void ++cpu_sig_intel (void) ++{ ++ uint32_t eax, ebx, ecx, edx; ++ char sig[13]; ++ ++ eax = CPUID_GET_HIGHEST_FUNCTION; ++ ebx = ecx = edx = 0; ++ ++ cpuid (&eax, &ebx, &ecx, &edx); ++ debug ("CPUID max function: %x %x %x %x\n", eax, ebx, ecx,edx); ++ ++ if (eax < CPUID_INTEL_TDX_ENUMERATION) ++ return; ++ ++ memset (sig, 0, sizeof sig); ++ cpuid_leaf (CPUID_INTEL_TDX_ENUMERATION, sig); ++ ++ if (memcmp (sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) ++ puts ("intel-tdx"); ++} ++ ++static void ++cpu_sig (void) ++{ ++ char sig[13]; ++ ++ memset (sig, 0, sizeof sig); ++ cpuid_leaf (0, sig); ++ ++ if (memcmp (sig, CPUID_SIG_AMD, sizeof(sig)) == 0) ++ cpu_sig_amd (); ++ else if (memcmp (sig, CPUID_SIG_INTEL, sizeof(sig)) == 0) ++ cpu_sig_intel (); ++} ++ ++#else /* !x86_64 */ ++ ++static void ++cpu_sig (void) ++{ ++ /* nothing for other architectures */ ++} ++ ++#endif ++ ++int ++main(int argc, char **argv) ++{ ++ int c; ++ ++ while (true) { ++ int option_index = 0; ++ static struct option long_options[] = { ++ {"debug", no_argument, 0, 'd' }, ++ {"version", no_argument, 0, 'v' }, ++ {"help", no_argument, 0, 'h'}, ++ {0, 0, 0, 0 } ++ }; ++ ++ c = getopt_long(argc, argv, "dvh", ++ long_options, &option_index); ++ if (c == -1) ++ break; ++ ++ switch (c) { ++ case 'd': ++ dodebug = true; ++ break; ++ case 'v': ++ fprintf(stdout, "%s\n", PACKAGE_VERSION); ++ exit(EXIT_SUCCESS); ++ break; ++ case 'h': ++ default: /* '?' */ ++ fprintf(c == 'h' ? stdout : stderr, ++ "Usage: %s [--debug|-d] [--help|-h] [--version|-v]\n", ++ argv[0]); ++ exit(c == 'h' ? EXIT_SUCCESS : EXIT_FAILURE); ++ } ++ } ++ ++ if (!dodebug) ++ setenv("TSS2_LOG", "all+none", 1); ++ ++ cpu_sig (); ++ ++ exit(EXIT_SUCCESS); ++} +diff --git a/virt-what-cvm.pod b/virt-what-cvm.pod +new file mode 100644 +index 000000000..12cfc6a96 +--- /dev/null ++++ b/virt-what-cvm.pod +@@ -0,0 +1,195 @@ ++=encoding utf8 ++ ++=head1 NAME ++ ++virt-what-cvm - detect if we are running in a confidential virtual machine ++ ++=head1 SUMMARY ++ ++virt-what-cvm [options] ++ ++=head1 DESCRIPTION ++ ++C is a tool which can be used to detect if the program ++is running in a confidential virtual machine. ++ ++The program prints out a list of "facts" about the confidential virtual ++machine, derived from heuristics. One fact is printed per line. ++ ++If nothing is printed and the script exits with code 0 (no error), ++then it can mean I that the program is running on bare-metal ++I the program is running inside a non-confidential virtual machine, ++I inside a type of confidential virtual machine which we don't know ++about or cannot detect. ++ ++=head1 FACTS ++ ++=over 4 ++ ++=item B ++ ++This is a confidential guest running with AMD SEV technology ++ ++Status: tested on Fedora 37 QEMU+KVM ++ ++=item B ++ ++This is a confidential guest running with AMD SEV-ES technology ++ ++Status: tested on Fedora 37 QEMU+KVM ++ ++=item B ++ ++This is a confidential guest running with AMD SEV-SNP technology ++ ++Status: tested on Microsoft Azure SEV-SNP CVM ++ ++Status: tested on Fedora 38 QEMU+KVM SEV-SNP (devel snapshot) ++ ++=item B ++ ++This is a confidential guest running with Intel TDX technology ++ ++Status: tested on Microsoft Azure TDX CVM (preview) ++ ++=item B ++ ++This is a confidential guest running unenlightened under the ++Azure HCL (Host Compatibility Layer). This will be paired with ++B. ++ ++Status: tested on Microsoft Azure SEV-SNP CVM ++ ++=back ++ ++=head1 EXIT STATUS ++ ++Programs that use or wrap C should check that the exit ++status is 0 before they attempt to parse the output of the command. ++ ++A non-zero exit status indicates some error, for example, an ++unrecognized command line argument. If the exit status is non-zero ++then the output "facts" (if any were printed) cannot be guaranteed and ++should be ignored. ++ ++The exit status does I have anything to do with whether the ++program is running on baremetal or under confidential virtualization, ++nor with whether C managed detection "correctly" (which ++is basically unknowable given the large variety of virtualization ++systems out there) ++ ++=head1 RUNNING VIRT-WHAT-CVM FROM OTHER PROGRAMS ++ ++C is designed so that you can easily run it from ++other programs or wrap it up in a library. ++ ++Your program should check the exit status (see the section above). ++ ++=head1 IMPORTANT NOTE ++ ++This program detects whether it is likely to be running within a known ++confidential VM, but does I prove that the environment is trustworthy. ++To attain trust in the environment requires an attestation report for the ++virtual machine, which is then verified by an already trusted 3rd party. ++ ++The hardware features that this program relies on to establish facts ++about the confidential virtualization environment, are those features ++whose behaviour will be proved by verification of an attestation report. ++ ++This program I have false positives. ie it may report that it is a ++confidential VM when it is in fact a non-confidential VM faking it. ++ ++This program I have false negatives. ie it should not fail to ++report existance of a confidential VM. Caveat that this only applies to ++environments which have been explicitly tested. ++ ++If this program does print a fact, this can be used for enabling or ++disabling use of certain features, according to whether they are ++appropriate for a confidential environment. None the less, the VM ++I be trusted until an attestation report is verified. ++ ++As a protection against false negatives from this tool, environments ++requiring high assurance should take one or more of these measures: ++ ++ * The facts reported by this program I should be measured ++ into one of the TPM PCRs ++ * The attestation report I cover the facts reported by ++ this program ++ * The attestation report I should cover the enablement ++ status of any features affected by decisions involving facts ++ reported by this tool ++ ++=head1 SEE ALSO ++ ++L, ++L, ++L ++ ++=head1 AUTHORS ++ ++Daniel P. Berrangé ++ ++=head1 COPYRIGHT ++ ++(C) Copyright 2023 Red Hat Inc., ++L ++ ++This program is free software; you can redistribute it and/or modify ++it under the terms of the GNU General Public License as published by ++the Free Software Foundation; either version 2 of the License, or ++(at your option) any later version. ++ ++This program is distributed in the hope that it will be useful, ++but WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++GNU General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; if not, write to the Free Software ++Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ++ ++=head1 REPORTING BUGS ++ ++Bugs can be viewed on the Red Hat Bugzilla page: ++L. ++ ++If you find a bug in virt-what-cvm, please follow these steps to report it: ++ ++=over 4 ++ ++=item 1. Check for existing bug reports ++ ++Go to L and search for similar bugs. ++Someone may already have reported the same bug, and they may even ++have fixed it. ++ ++=item 2. Capture debug and error messages ++ ++Run ++ ++ virt-what-cvm -d > virt-what-cvm.log 2>&1 ++ ++and keep I. It may contain error messages which you ++should submit with your bug report. ++ ++=item 3. Get version of virt-what-cvm. ++ ++Run ++ ++ virt-what-cvm --version ++ ++=item 4. Submit a bug report. ++ ++Go to L and enter a new bug. ++Please describe the problem in as much detail as possible. ++ ++Remember to include the version numbers (step 3) and the debug ++messages file (step 2) and as much other detail as possible. ++ ++=item 5. Assign the bug to rjones @ redhat.com ++ ++Assign or reassign the bug to B (without the ++spaces). You can also send me an email with the bug number if you ++want a faster response. ++ ++=back +-- +2.43.0 + diff --git a/SOURCES/0010-docs-Add-cross-reference-to-virt-what-cvm-1-to-virt-.patch b/SOURCES/0010-docs-Add-cross-reference-to-virt-what-cvm-1-to-virt-.patch new file mode 100644 index 0000000..8cc5738 --- /dev/null +++ b/SOURCES/0010-docs-Add-cross-reference-to-virt-what-cvm-1-to-virt-.patch @@ -0,0 +1,25 @@ +From dbd90b1a4ceae884b06907da0b7964bcb8ff01d3 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 30 May 2023 08:46:06 +0100 +Subject: [PATCH] docs: Add cross reference to virt-what-cvm(1) to virt-what(1) + +(cherry picked from commit 52c833c7c6ede0b7fcefa7ad225206f410407eda) +--- + virt-what.pod | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/virt-what.pod b/virt-what.pod +index 45dd7c933..d60449d02 100644 +--- a/virt-what.pod ++++ b/virt-what.pod +@@ -409,6 +409,7 @@ specific features your drivers need (eg. for the presence of PCI devices). + + =head1 SEE ALSO + ++L, + L, + L, + L, +-- +2.43.0 + diff --git a/SOURCES/0011-virt-what-cvm-check-if-hypervisor-bit-is-set.patch b/SOURCES/0011-virt-what-cvm-check-if-hypervisor-bit-is-set.patch new file mode 100644 index 0000000..b3f1bc3 --- /dev/null +++ b/SOURCES/0011-virt-what-cvm-check-if-hypervisor-bit-is-set.patch @@ -0,0 +1,77 @@ +From 0b4886bea5fce89f588a1ac3c885b6860bb2deed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 29 Jun 2023 17:51:02 +0100 +Subject: [PATCH] virt-what-cvm: check if hypervisor bit is set +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Before doing any probes for a confidential VM, check that the +tool is running under a hypervisor, rather than bare metal + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 64718d09a504bd10c6ab973acc0779925482b62f) +--- + virt-what-cvm.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index 407efb492..f1847688b 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -35,6 +35,9 @@ static bool dodebug = false; + + #define debug(...) do { if (dodebug) fprintf(stderr, __VA_ARGS__); } while(0) + ++ ++#define CPUID_PROCESSOR_INFO_AND_FEATURE_BITS 0x1 ++ + /* + * AMD64 Architecture Programmer’s Manual Volume 3: + * General-Purpose and System Instructions. +@@ -72,6 +75,9 @@ static bool dodebug = false; + #define CPUID_SIG_INTEL "GenuineIntel" + #define CPUID_SIG_INTEL_TDX "IntelTDX " + ++/* ecx bit 31: set => hyperpvisor, unset => bare metal */ ++#define CPUID_FEATURE_HYPERVISOR (1 << 31) ++ + /* + * This TPM NV data format is not explicitly documented anywhere, + * but the header definition is present in code at: +@@ -335,11 +341,32 @@ cpu_sig_intel (void) + puts ("intel-tdx"); + } + ++static bool ++cpu_is_hv (void) ++{ ++ uint32_t eax, ebx, ecx, edx; ++ bool is_hv; ++ ++ eax = CPUID_PROCESSOR_INFO_AND_FEATURE_BITS; ++ ebx = ecx = edx = 0; ++ ++ cpuid(&eax, &ebx, &ecx, &edx); ++ ++ is_hv = ecx & CPUID_FEATURE_HYPERVISOR; ++ ++ debug ("CPUID is hypervisor: %s\n", is_hv ? "yes" : "no"); ++ return is_hv; ++} ++ + static void + cpu_sig (void) + { + char sig[13]; + ++ /* Skip everything on bare metal */ ++ if (!cpu_is_hv ()) ++ return; ++ + memset (sig, 0, sizeof sig); + cpuid_leaf (0, sig); + +-- +2.43.0 + diff --git a/SOURCES/0012-virt-what-cvm-support-alternative-cpuid-leaf-orderin.patch b/SOURCES/0012-virt-what-cvm-support-alternative-cpuid-leaf-orderin.patch new file mode 100644 index 0000000..6449715 --- /dev/null +++ b/SOURCES/0012-virt-what-cvm-support-alternative-cpuid-leaf-orderin.patch @@ -0,0 +1,59 @@ +From 56498baf2eddf072b9dcab7570febc6ce8f58504 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 29 Jun 2023 17:51:03 +0100 +Subject: [PATCH] virt-what-cvm: support alternative cpuid leaf ordering +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The HyperV CPUID leaf for reporting the vendor string has an +alternative ordering of ecx/edx. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 15d3e4a92fd9c1490fb6f86b7ab3a2dff8364837) +--- + virt-what-cvm.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index f1847688b..1e7c50bb0 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -209,11 +209,14 @@ cpuid (uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + + + static uint32_t +-cpuid_leaf (uint32_t eax, char *sig) ++cpuid_leaf (uint32_t eax, char *sig, bool swapped) + { + uint32_t *sig32 = (uint32_t *) sig; + +- cpuid (&eax, &sig32[0], &sig32[2], &sig32[1]); ++ if (swapped) ++ cpuid (&eax, &sig32[0], &sig32[2], &sig32[1]); ++ else ++ cpuid (&eax, &sig32[0], &sig32[1], &sig32[2]); + sig[12] = 0; /* \0-terminate the string to make string comparison possible */ + debug("CPUID sig %s\n", sig); + return eax; +@@ -335,7 +338,7 @@ cpu_sig_intel (void) + return; + + memset (sig, 0, sizeof sig); +- cpuid_leaf (CPUID_INTEL_TDX_ENUMERATION, sig); ++ cpuid_leaf (CPUID_INTEL_TDX_ENUMERATION, sig, true); + + if (memcmp (sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) + puts ("intel-tdx"); +@@ -368,7 +371,7 @@ cpu_sig (void) + return; + + memset (sig, 0, sizeof sig); +- cpuid_leaf (0, sig); ++ cpuid_leaf (0, sig, true); + + if (memcmp (sig, CPUID_SIG_AMD, sizeof(sig)) == 0) + cpu_sig_amd (); +-- +2.43.0 + diff --git a/SOURCES/0013-virt-what-cvm-probe-for-SNP-HCL-on-HyperV-Azure-via-.patch b/SOURCES/0013-virt-what-cvm-probe-for-SNP-HCL-on-HyperV-Azure-via-.patch new file mode 100644 index 0000000..25df415 --- /dev/null +++ b/SOURCES/0013-virt-what-cvm-probe-for-SNP-HCL-on-HyperV-Azure-via-.patch @@ -0,0 +1,117 @@ +From eecffe8b20d7e136e64d7360ef6655c8eee4250e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 29 Jun 2023 17:51:04 +0100 +Subject: [PATCH] virt-what-cvm: probe for SNP/HCL on HyperV/Azure via CPUID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When running a confidential VM on Azure (HyperV) we can probe +CPUID leaf 0x40000003 to detect if VM isolation is present, +and 0x4000000c to detect what kind of isolation is used. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit bb0055b491501e16fca3ab61dc7a969effbf48f3) +--- + virt-what-cvm.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 60 insertions(+), 2 deletions(-) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index 1e7c50bb0..a7a224f94 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -70,14 +70,33 @@ static bool dodebug = false; + + #define CPUID_INTEL_TDX_ENUMERATION 0x21 + ++/* Requirements for Implementing the Microsoft Hypervisor Interface ++ * https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/tlfs ++ */ ++#define CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS 0x40000000 ++ ++#define CPUID_HYPERV_FEATURES 0x40000003 ++ ++#define CPUID_HYPERV_ISOLATION_CONFIG 0x4000000C ++ ++#define CPUID_HYPERV_MIN 0x40000005 ++#define CPUID_HYPERV_MAX 0x4000ffff + + #define CPUID_SIG_AMD "AuthenticAMD" + #define CPUID_SIG_INTEL "GenuineIntel" + #define CPUID_SIG_INTEL_TDX "IntelTDX " ++#define CPUID_SIG_HYPERV "Microsoft Hv" + + /* ecx bit 31: set => hyperpvisor, unset => bare metal */ + #define CPUID_FEATURE_HYPERVISOR (1 << 31) + ++/* Linux include/asm-generic/hyperv-tlfs.h */ ++#define CPUID_HYPERV_CPU_MANAGEMENT (1 << 12) /* root partition */ ++#define CPUID_HYPERV_ISOLATION (1 << 22) /* confidential VM partition */ ++ ++#define CPUID_HYPERV_ISOLATION_TYPE_MASK 0xf ++#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 ++ + /* + * This TPM NV data format is not explicitly documented anywhere, + * but the header definition is present in code at: +@@ -272,6 +291,44 @@ cpu_sig_amd_azure (void) + return ret; + } + ++static bool ++cpu_sig_amd_hyperv (void) ++{ ++ uint32_t eax, ebx, ecx, edx; ++ char sig[13]; ++ uint32_t feat; ++ ++ feat = cpuid_leaf (CPUID_HYPERV_VENDOR_AND_MAX_FUNCTIONS, sig, false); ++ ++ if (feat < CPUID_HYPERV_MIN || ++ feat > CPUID_HYPERV_MAX) ++ return false; ++ ++ if (memcmp (sig, CPUID_SIG_HYPERV, sizeof(sig)) != 0) ++ return false; ++ ++ debug ("CPUID is on hyperv\n"); ++ eax = CPUID_HYPERV_FEATURES; ++ ebx = ecx = edx = 0; ++ ++ cpuid(&eax, &ebx, &ecx, &edx); ++ ++ if (ebx & CPUID_HYPERV_ISOLATION && ++ !(ebx & CPUID_HYPERV_CPU_MANAGEMENT)) { ++ ++ eax = CPUID_HYPERV_ISOLATION_CONFIG; ++ ebx = ecx = edx = 0; ++ cpuid(&eax, &ebx, &ecx, &edx); ++ ++ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == ++ CPUID_HYPERV_ISOLATION_TYPE_SNP) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++ + static void + cpu_sig_amd (void) + { +@@ -298,9 +355,10 @@ cpu_sig_amd (void) + * exposes a SEV-SNP attestation report as evidence. + */ + if (!(eax & (1 << 1))) { +- debug ("No sev in CPUID, try azure TPM NV\n"); ++ debug ("No sev in CPUID, try hyperv CPUID/azure TPM NV\n"); + +- if (cpu_sig_amd_azure()) { ++ if (cpu_sig_amd_hyperv () || ++ cpu_sig_amd_azure()) { + puts ("amd-sev-snp"); + puts ("azure-hcl"); + } else { +-- +2.43.0 + diff --git a/SOURCES/0014-virt-what-cvm-drop-TPM-logic-for-detecting-SNP-on-Hy.patch b/SOURCES/0014-virt-what-cvm-drop-TPM-logic-for-detecting-SNP-on-Hy.patch new file mode 100644 index 0000000..8afe804 --- /dev/null +++ b/SOURCES/0014-virt-what-cvm-drop-TPM-logic-for-detecting-SNP-on-Hy.patch @@ -0,0 +1,258 @@ +From 5658e72cb0de7e0e31fd16df7a3b80015ce6dc71 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 29 Jun 2023 17:51:05 +0100 +Subject: [PATCH] virt-what-cvm: drop TPM logic for detecting SNP on + HyperV/Azure +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Now we have proper CPUID detection, we no longer need the TPM +hacks. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 82c0e9c469953a36f18db1e329629cecd950134a) +--- + Makefile.am | 3 - + configure.ac | 2 - + virt-what-cvm.c | 161 ++---------------------------------------------- + 3 files changed, 6 insertions(+), 160 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 2050bef8d..b68540f39 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -30,9 +30,6 @@ if HOST_CPU_IA64 + libexec_PROGRAMS += virt-what-ia64-xen-rdtsc-test + endif + +-virt_what_cvm_LDADD = $(TPM2_TSS_LIBS) +-virt_what_cvm_CFLAGS = $(TPM2_TSS_CFLAGS) +- + if HAVE_POD2MAN + + CLEANFILES += virt-what.1 virt-what-cvm.1 virt-what.txt virt-what-cvm.txt +diff --git a/configure.ac b/configure.ac +index b1dadd64d..0309a80bd 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -32,8 +32,6 @@ dnl Architecture we are compiling for. + AC_CANONICAL_HOST + AM_CONDITIONAL([HOST_CPU_IA64], [ test "x$host_cpu" = "xia64" ]) + +-PKG_HAVE_DEFINE_WITH_MODULES(TPM2_TSS, tss2-esys, [tpm2-tss package]) +- + + dnl List of tests. + tests="\ +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index a7a224f94..8b8a4df09 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -26,10 +26,6 @@ + #include + #include + #include +-#ifdef HAVE_TPM2_TSS +-#include +-#include +-#endif + + static bool dodebug = false; + +@@ -97,121 +93,8 @@ static bool dodebug = false; + #define CPUID_HYPERV_ISOLATION_TYPE_MASK 0xf + #define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 + +-/* +- * This TPM NV data format is not explicitly documented anywhere, +- * but the header definition is present in code at: +- * +- * https://github.com/kinvolk/azure-cvm-tooling/blob/main/az-snp-vtpm/src/hcl.rs +- */ +-#define TPM_AZURE_HCLA_REPORT_INDEX 0x01400001 +- +-struct TPMAzureHCLAHeader { +- uint32_t signature; +- uint32_t version; +- uint32_t report_len; +- uint32_t report_type; +- uint32_t unknown[4]; +-}; +- +-/* The bytes for "HCLA" */ +-#define TPM_AZURE_HCLA_SIGNATURE 0x414C4348 +-#define TPM_AZURE_HCLA_VERSION 0x1 +-#define TPM_AZURE_HCLA_REPORT_TYPE_SNP 0x2 +- + #if defined(__x86_64__) + +-#ifdef HAVE_TPM2_TSS +-static char * +-tpm_nvread(uint32_t nvindex, size_t *retlen) +-{ +- TSS2_RC rc; +- ESYS_CONTEXT *ctx = NULL; +- ESYS_TR primary = ESYS_TR_NONE; +- ESYS_TR session = ESYS_TR_NONE; +- ESYS_TR nvobj = ESYS_TR_NONE; +- TPM2B_NV_PUBLIC *pubData = NULL; +- TPMT_SYM_DEF sym = { +- .algorithm = TPM2_ALG_AES, +- .keyBits = { .aes = 128 }, +- .mode = { .aes = TPM2_ALG_CFB } +- }; +- char *ret; +- size_t retwant; +- +- rc = Esys_Initialize(&ctx, NULL, NULL); +- if (rc != TSS2_RC_SUCCESS) +- return NULL; +- +- rc = Esys_Startup(ctx, TPM2_SU_CLEAR); +- debug("tpm startup %d\n", rc); +- if (rc != TSS2_RC_SUCCESS) +- goto error; +- +- rc = Esys_StartAuthSession(ctx, ESYS_TR_NONE, ESYS_TR_NONE, +- ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, +- NULL, 0, +- &sym, TPM2_ALG_SHA256, &session); +- debug("tpm auth session %d\n", rc); +- if (rc != TSS2_RC_SUCCESS) +- goto error; +- +- rc = Esys_TR_FromTPMPublic(ctx, nvindex, ESYS_TR_NONE, +- ESYS_TR_NONE, ESYS_TR_NONE, &nvobj); +- debug("tpm from public %d\n", rc); +- if (rc != TSS2_RC_SUCCESS) +- goto error; +- +- rc = Esys_NV_ReadPublic(ctx, nvobj, ESYS_TR_NONE, +- ESYS_TR_NONE, ESYS_TR_NONE, +- &pubData, NULL); +- debug("tpm read public %d\n", rc); +- if (rc != TPM2_RC_SUCCESS) +- goto error; +- +- retwant = pubData->nvPublic.dataSize; +- free(pubData); +- *retlen = 0; +- ret = malloc(retwant); +- assert(ret); +- while (*retlen < retwant) { +- size_t want = retwant - *retlen; +- TPM2B_MAX_NV_BUFFER *data = NULL; +- if (want > 1024) +- want = 1024; +- rc = Esys_NV_Read(ctx, ESYS_TR_RH_OWNER, nvobj, session, ESYS_TR_NONE, ESYS_TR_NONE, +- want, *retlen, &data); +- debug("tpm nv read %d\n", rc); +- if (rc != TPM2_RC_SUCCESS) { +- free(ret); +- goto error; +- } +- +- memcpy(ret + *retlen, data->buffer, data->size); +- *retlen += data->size; +- free(data); +- } +- +- return ret; +- +- error: +- if (nvobj != ESYS_TR_NONE) +- Esys_FlushContext(ctx, nvobj); +- if (session != ESYS_TR_NONE) +- Esys_FlushContext(ctx, session); +- if (primary != ESYS_TR_NONE) +- Esys_FlushContext(ctx, primary); +- Esys_Finalize(&ctx); +- *retlen = 0; +- return NULL; +-} +-#else /* ! HAVE_TPM2_TSS */ +-static char * +-tpm_nvread(uint32_t nvindex, size_t *retlen) +-{ +- return NULL; +-} +-#endif /* ! HAVE_TPM2_TSS */ +- + /* Copied from the Linux kernel definition in + * arch/x86/include/asm/processor.h + */ +@@ -263,34 +146,6 @@ msr (off_t index) + return ret; + } + +-bool +-cpu_sig_amd_azure (void) +-{ +- size_t datalen = 0; +- char *data = tpm_nvread(TPM_AZURE_HCLA_REPORT_INDEX, &datalen); +- struct TPMAzureHCLAHeader *header = (struct TPMAzureHCLAHeader *)data; +- bool ret; +- +- if (!data) +- return false; +- +- if (datalen < sizeof(struct TPMAzureHCLAHeader)) { +- debug ("TPM data len is too small to be an Azure HCLA report"); +- return false; +- } +- +- debug ("Azure TPM HCLA report header sig %x ver %x type %x\n", +- header->signature, header->version, header->report_type); +- +- ret = (header->signature == TPM_AZURE_HCLA_SIGNATURE && +- header->version == TPM_AZURE_HCLA_VERSION && +- header->report_type == TPM_AZURE_HCLA_REPORT_TYPE_SNP); +- debug ("Azure TPM HCLA report present ? %d\n", ret); +- +- free(data); +- return ret; +-} +- + static bool + cpu_sig_amd_hyperv (void) + { +@@ -350,19 +205,18 @@ cpu_sig_amd (void) + + /* bit 1 == CPU supports SEV feature + * +- * Note, Azure blocks this CPUID leaf from its SEV-SNP +- * guests, so we must fallback to probing the TPM which +- * exposes a SEV-SNP attestation report as evidence. ++ * Note, HyperV/Azure blocks this CPUID leaf from its SEV-SNP ++ * guests. We already did an alternative detection mechanism ++ * in such VMs, so should not even be running this code. + */ + if (!(eax & (1 << 1))) { +- debug ("No sev in CPUID, try hyperv CPUID/azure TPM NV\n"); ++ debug ("No sev in CPUID, try hyperv CPUID\n"); + +- if (cpu_sig_amd_hyperv () || +- cpu_sig_amd_azure()) { ++ if (cpu_sig_amd_hyperv ()) { + puts ("amd-sev-snp"); + puts ("azure-hcl"); + } else { +- debug("No azure TPM NV\n"); ++ debug("No hyperv CPUID\n"); + } + return; + } +@@ -483,9 +337,6 @@ main(int argc, char **argv) + } + } + +- if (!dodebug) +- setenv("TSS2_LOG", "all+none", 1); +- + cpu_sig (); + + exit(EXIT_SUCCESS); +-- +2.43.0 + diff --git a/SOURCES/0015-virt-what-cvm-rename-azure-hcl-fact-to-hyperv-hcl.patch b/SOURCES/0015-virt-what-cvm-rename-azure-hcl-fact-to-hyperv-hcl.patch new file mode 100644 index 0000000..8c67662 --- /dev/null +++ b/SOURCES/0015-virt-what-cvm-rename-azure-hcl-fact-to-hyperv-hcl.patch @@ -0,0 +1,53 @@ +From fc766c6db5305effdaaaa843d6a2c2b4623c8b99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Thu, 29 Jun 2023 17:51:06 +0100 +Subject: [PATCH] virt-what-cvm: rename 'azure-hcl' fact to 'hyperv-hcl' +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Azure is a cloud service that uses the HyperV platform, so we +should refer to the fact as 'hyperv-hcl', not 'azure-hcl'. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 94773022f76f994d7a9b37f59ba978bd28f30d1d) +--- + virt-what-cvm.c | 2 +- + virt-what-cvm.pod | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index 8b8a4df09..52b3426bc 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -214,7 +214,7 @@ cpu_sig_amd (void) + + if (cpu_sig_amd_hyperv ()) { + puts ("amd-sev-snp"); +- puts ("azure-hcl"); ++ puts ("hyperv-hcl"); + } else { + debug("No hyperv CPUID\n"); + } +diff --git a/virt-what-cvm.pod b/virt-what-cvm.pod +index 12cfc6a96..0f9076569 100644 +--- a/virt-what-cvm.pod ++++ b/virt-what-cvm.pod +@@ -52,11 +52,11 @@ This is a confidential guest running with Intel TDX technology + + Status: tested on Microsoft Azure TDX CVM (preview) + +-=item B ++=item B + + This is a confidential guest running unenlightened under the +-Azure HCL (Host Compatibility Layer). This will be paired with +-B. ++HyperV (Azure) HCL (Host Compatibility Layer). This will be ++paired with B. + + Status: tested on Microsoft Azure SEV-SNP CVM + +-- +2.43.0 + diff --git a/SOURCES/0016-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch b/SOURCES/0016-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch new file mode 100644 index 0000000..1f80123 --- /dev/null +++ b/SOURCES/0016-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch @@ -0,0 +1,26 @@ +From c8daee800cbe22e622306f78a71188ec5639d4a1 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Fri, 26 Jul 2024 16:05:12 +0100 +Subject: [PATCH] Add virt-what-cvm.pod to EXTRA_DIST + +(Single hunk cherry pick from commit 6d1455766b) +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index b68540f39..ba5185741 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -19,7 +19,7 @@ AM_CPPFLAGS = -Wall + + CLEANFILES = virt-what *~ + +-EXTRA_DIST = .gitignore virt-what.in virt-what.pod ++EXTRA_DIST = .gitignore virt-what.in virt-what.pod virt-what-cvm.pod + + SUBDIRS = . tests + +-- +2.43.0 + diff --git a/SOURCES/0017-Fix-CVM-detection-on-Azure-with-TDX.patch b/SOURCES/0017-Fix-CVM-detection-on-Azure-with-TDX.patch new file mode 100644 index 0000000..95e88b5 --- /dev/null +++ b/SOURCES/0017-Fix-CVM-detection-on-Azure-with-TDX.patch @@ -0,0 +1,98 @@ +From 7b19a3a531fbabb5785dc7f78352d574f079212f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Tue, 30 Jul 2024 10:46:46 +0100 +Subject: [PATCH] Fix CVM detection on Azure with TDX +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The current TDX support was tested on Azure, however, since that time +they now block the CPUID leaf we were using. Instead it is required to +issue the Azure specific CPUID calls as we were already doing for SNP. + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 059cbff66740ef74cd663f88c5f96a80a8d6d6ea) +--- + virt-what-cvm.c | 14 +++++++++----- + virt-what-cvm.pod | 4 ++-- + 2 files changed, 11 insertions(+), 7 deletions(-) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index 52b3426bc..0daa6ac35 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -92,6 +92,7 @@ static bool dodebug = false; + + #define CPUID_HYPERV_ISOLATION_TYPE_MASK 0xf + #define CPUID_HYPERV_ISOLATION_TYPE_SNP 2 ++#define CPUID_HYPERV_ISOLATION_TYPE_TDX 3 + + #if defined(__x86_64__) + +@@ -147,7 +148,7 @@ msr (off_t index) + } + + static bool +-cpu_sig_amd_hyperv (void) ++cpu_sig_cvm_hyperv (uint32_t isoltype) + { + uint32_t eax, ebx, ecx, edx; + char sig[13]; +@@ -175,8 +176,7 @@ cpu_sig_amd_hyperv (void) + ebx = ecx = edx = 0; + cpuid(&eax, &ebx, &ecx, &edx); + +- if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == +- CPUID_HYPERV_ISOLATION_TYPE_SNP) { ++ if ((ebx & CPUID_HYPERV_ISOLATION_TYPE_MASK) == isoltype) { + return true; + } + } +@@ -212,7 +212,7 @@ cpu_sig_amd (void) + if (!(eax & (1 << 1))) { + debug ("No sev in CPUID, try hyperv CPUID\n"); + +- if (cpu_sig_amd_hyperv ()) { ++ if (cpu_sig_cvm_hyperv (CPUID_HYPERV_ISOLATION_TYPE_SNP)) { + puts ("amd-sev-snp"); + puts ("hyperv-hcl"); + } else { +@@ -252,8 +252,12 @@ cpu_sig_intel (void) + memset (sig, 0, sizeof sig); + cpuid_leaf (CPUID_INTEL_TDX_ENUMERATION, sig, true); + +- if (memcmp (sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) ++ if (memcmp (sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0) { + puts ("intel-tdx"); ++ } else if (cpu_sig_cvm_hyperv (CPUID_HYPERV_ISOLATION_TYPE_TDX)) { ++ puts ("intel-tdx"); ++ puts ("hyperv-hcl"); ++ } + } + + static bool +diff --git a/virt-what-cvm.pod b/virt-what-cvm.pod +index 0f9076569..70213abd7 100644 +--- a/virt-what-cvm.pod ++++ b/virt-what-cvm.pod +@@ -50,7 +50,7 @@ Status: tested on Fedora 38 QEMU+KVM SEV-SNP (devel snapshot) + + This is a confidential guest running with Intel TDX technology + +-Status: tested on Microsoft Azure TDX CVM (preview) ++Status: tested on Microsoft Azure TDX CVM + + =item B + +@@ -58,7 +58,7 @@ This is a confidential guest running unenlightened under the + HyperV (Azure) HCL (Host Compatibility Layer). This will be + paired with B. + +-Status: tested on Microsoft Azure SEV-SNP CVM ++Status: tested on Microsoft Azure SEV-SNP & TDX CVM + + =back + +-- +2.43.0 + diff --git a/SOURCES/0018-Add-support-for-detecting-protected-virtualization-o.patch b/SOURCES/0018-Add-support-for-detecting-protected-virtualization-o.patch new file mode 100644 index 0000000..e583241 --- /dev/null +++ b/SOURCES/0018-Add-support-for-detecting-protected-virtualization-o.patch @@ -0,0 +1,66 @@ +From d1cedcffeeff58f33aa467d62c0347ce7073aa4e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= +Date: Fri, 2 Aug 2024 16:07:46 +0100 +Subject: [PATCH] Add support for detecting protected virtualization on s390x +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: Daniel P. Berrangé +(cherry picked from commit 037689fbe95e403b050c1eb736ebc8fdc2e601a5) +--- + virt-what-cvm.c | 21 ++++++++++++++++++++- + virt-what-cvm.pod | 5 +++++ + 2 files changed, 25 insertions(+), 1 deletion(-) + +diff --git a/virt-what-cvm.c b/virt-what-cvm.c +index 0daa6ac35..320df478b 100644 +--- a/virt-what-cvm.c ++++ b/virt-what-cvm.c +@@ -295,7 +295,26 @@ cpu_sig (void) + cpu_sig_intel (); + } + +-#else /* !x86_64 */ ++#elif defined(__s390x__) ++ ++#define SYSFS_PROT_VIRT "/sys/firmware/uv/prot_virt_guest" ++ ++static void ++cpu_sig (void) ++{ ++ int fd = open("/sys/firmware/uv/prot_virt_guest", O_RDONLY); ++ char c; ++ if (fd < 0) ++ return; ++ ++ if (read(fd, &c, 1) == 1 && c == '1') ++ puts("s390-protvirt"); ++ ++ close(fd); ++} ++ ++ ++#else /* ! x86_64 && ! s390x */ + + static void + cpu_sig (void) +diff --git a/virt-what-cvm.pod b/virt-what-cvm.pod +index 70213abd7..00e21cb70 100644 +--- a/virt-what-cvm.pod ++++ b/virt-what-cvm.pod +@@ -60,6 +60,11 @@ paired with B. + + Status: tested on Microsoft Azure SEV-SNP & TDX CVM + ++=item B ++ ++This is a confidential guest running on s390x with the ++Protected Virtualization (Secure Execution) technology ++ + =back + + =head1 EXIT STATUS +-- +2.43.0 + diff --git a/SOURCES/0019-virt-what-cvm.pod-Fix-man-page-typo-s390x-protvirt-s.patch b/SOURCES/0019-virt-what-cvm.pod-Fix-man-page-typo-s390x-protvirt-s.patch new file mode 100644 index 0000000..3dd6130 --- /dev/null +++ b/SOURCES/0019-virt-what-cvm.pod-Fix-man-page-typo-s390x-protvirt-s.patch @@ -0,0 +1,29 @@ +From 69e5ae90a5a95b38d765e110acf76b3fe3c2665a Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 13 Aug 2024 13:23:06 +0100 +Subject: [PATCH] virt-what-cvm.pod: Fix man page typo s390x-protvirt -> + s390-protvirt + +Reported-by: Yongkui Guo +Fixes: commit 037689fbe95e403b050c1eb736ebc8fdc2e601a5 +(cherry picked from commit 963676c4dd4c2a9c070b76da6f8835ceb131dbe0) +--- + virt-what-cvm.pod | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/virt-what-cvm.pod b/virt-what-cvm.pod +index 00e21cb70..a76717984 100644 +--- a/virt-what-cvm.pod ++++ b/virt-what-cvm.pod +@@ -60,7 +60,7 @@ paired with B. + + Status: tested on Microsoft Azure SEV-SNP & TDX CVM + +-=item B ++=item B + + This is a confidential guest running on s390x with the + Protected Virtualization (Secure Execution) technology +-- +2.43.0 + diff --git a/SOURCES/copy-patches.sh b/SOURCES/copy-patches.sh index 9047e8b..a588d59 100755 --- a/SOURCES/copy-patches.sh +++ b/SOURCES/copy-patches.sh @@ -8,7 +8,7 @@ set -e # ./copy-patches.sh project=virt-what -rhel_version=9.3 +rhel_version=9.5 # Check we're in the right directory. if [ ! -f $project.spec ]; then diff --git a/SPECS/virt-what.spec b/SPECS/virt-what.spec index 3131960..beaf5bd 100644 --- a/SPECS/virt-what.spec +++ b/SPECS/virt-what.spec @@ -1,6 +1,6 @@ Name: virt-what Version: 1.25 -Release: 5%{?dist} +Release: 10%{?dist} Summary: Detect if we are running in a virtual machine License: GPLv2+ @@ -11,7 +11,7 @@ Source0: http://people.redhat.com/~rjones/virt-what/files/%{name}-%{versi Source1: copy-patches.sh # Patches are maintained in the following repository: -# http://git.annexia.org/?p=virt-what.git;a=shortlog;h=refs/heads/rhel-9.3 +# http://git.annexia.org/?p=virt-what.git;a=shortlog;h=refs/heads/rhel-9.5 # Patches. Patch0001: 0001-Rearrange-lxc-test-to-avoid-use-of-cat.patch @@ -21,6 +21,18 @@ Patch0004: 0004-Detect-OCI-containers.patch Patch0005: 0005-Add-support-for-Alibaba-cloud-on-aarch64.patch Patch0006: 0006-nutanix-Don-t-match-Nutanix-based-baremetal-systems.patch Patch0007: 0007-Add-support-for-CRI-O-containers.patch +Patch0008: 0008-Fix-support-for-Hyper-V-on-Arm.patch +Patch0009: 0009-Introduce-virt-what-cvm-program.patch +Patch0010: 0010-docs-Add-cross-reference-to-virt-what-cvm-1-to-virt-.patch +Patch0011: 0011-virt-what-cvm-check-if-hypervisor-bit-is-set.patch +Patch0012: 0012-virt-what-cvm-support-alternative-cpuid-leaf-orderin.patch +Patch0013: 0013-virt-what-cvm-probe-for-SNP-HCL-on-HyperV-Azure-via-.patch +Patch0014: 0014-virt-what-cvm-drop-TPM-logic-for-detecting-SNP-on-Hy.patch +Patch0015: 0015-virt-what-cvm-rename-azure-hcl-fact-to-hyperv-hcl.patch +Patch0016: 0016-Add-virt-what-cvm.pod-to-EXTRA_DIST.patch +Patch0017: 0017-Fix-CVM-detection-on-Azure-with-TDX.patch +Patch0018: 0018-Add-support-for-detecting-protected-virtualization-o.patch +Patch0019: 0019-virt-what-cvm.pod-Fix-man-page-typo-s390x-protvirt-s.patch BuildRequires: make BuildRequires: git @@ -122,11 +134,24 @@ fi %files %doc README COPYING %{_sbindir}/virt-what +%{_sbindir}/virt-what-cvm %{_libexecdir}/virt-what-cpuid-helper %{_mandir}/man1/*.1* %changelog +* Tue Aug 13 2024 Richard W.M. Jones - 1.25-10 +- Implement virt-what-cvm for s390x + related: RHEL-50659 + +* Tue Jul 30 2024 Richard W.M. Jones - 1.25-8 +- Add virt-what-cvm tool + resolves: RHEL-50659 + +* Tue Jul 02 2024 Richard W.M. Jones - 1.25-6 +- Add support for Azure VMs on ARM + resolves: RHEL-45834 + * Wed Jun 28 2023 Richard W.M. Jones - 1.25-5 - Add support for CRI-O containers resolves: rhbz#2218203