systemd-252-43
Resolves: RHEL-50103,RHEL-50651
This commit is contained in:
parent
a9a01af816
commit
79df79b44e
@ -0,0 +1,31 @@
|
||||
From 366cfe45170487488d33997f832487f8841556c7 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Tue, 1 Aug 2023 03:22:57 +0900
|
||||
Subject: [PATCH] udev-builtin-net_id: skip non-directory entry earlier
|
||||
|
||||
In the below, we will try to read 'address' file in the directory,
|
||||
hence the entry must be a directory.
|
||||
|
||||
No functional change, just a tiny optimization.
|
||||
|
||||
(cherry picked from commit 4103dca1b5664f937ce125219ca70ea54f810ac8)
|
||||
|
||||
Related: RHEL-50103
|
||||
---
|
||||
src/udev/udev-builtin-net_id.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||
index c20df41c37..40f7454ba0 100644
|
||||
--- a/src/udev/udev-builtin-net_id.c
|
||||
+++ b/src/udev/udev-builtin-net_id.c
|
||||
@@ -441,6 +441,9 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
if (dot_or_dot_dot(de->d_name))
|
||||
continue;
|
||||
|
||||
+ if (de->d_type != DT_DIR)
|
||||
+ continue;
|
||||
+
|
||||
r = safe_atou32(de->d_name, &i);
|
||||
if (r < 0 || i <= 0)
|
||||
continue;
|
@ -0,0 +1,72 @@
|
||||
From f1dc0bef81dbb101dcc53545accbe680a548d3eb Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Tue, 1 Aug 2023 03:25:39 +0900
|
||||
Subject: [PATCH] udev-builtin-net_id: return earlier when hotplug slot is not
|
||||
found
|
||||
|
||||
Then we can reduce indentation.
|
||||
No functional change, just refactoring.
|
||||
|
||||
(cherry picked from commit 73fb4b20c1f653619286b2e9ce51c19169ccbfc6)
|
||||
|
||||
Related: RHEL-50103
|
||||
---
|
||||
src/udev/udev-builtin-net_id.c | 45 +++++++++++++++++-----------------
|
||||
1 file changed, 23 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||
index 40f7454ba0..5e76a894f7 100644
|
||||
--- a/src/udev/udev-builtin-net_id.c
|
||||
+++ b/src/udev/udev-builtin-net_id.c
|
||||
@@ -487,28 +487,29 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
rewinddir(dir);
|
||||
}
|
||||
|
||||
- if (hotplug_slot > 0) {
|
||||
- s = names->pci_slot;
|
||||
- l = sizeof(names->pci_slot);
|
||||
- if (domain > 0)
|
||||
- l = strpcpyf(&s, l, "P%u", domain);
|
||||
- l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot);
|
||||
- if (func > 0 || is_pci_multifunction(names->pcidev) > 0)
|
||||
- l = strpcpyf(&s, l, "f%u", func);
|
||||
- if (naming_scheme_has(NAMING_SR_IOV_R) && info->vf_representor_id >= 0)
|
||||
- /* For VF representor append 'r<VF_NUM>' and not phys_port_name */
|
||||
- l = strpcpyf(&s, l, "r%d", info->vf_representor_id);
|
||||
- else if (!isempty(info->phys_port_name))
|
||||
- l = strpcpyf(&s, l, "n%s", info->phys_port_name);
|
||||
- else if (dev_port > 0)
|
||||
- l = strpcpyf(&s, l, "d%lu", dev_port);
|
||||
- if (l == 0)
|
||||
- names->pci_slot[0] = '\0';
|
||||
-
|
||||
- log_device_debug(dev, "Slot identifier: domain=%u slot=%"PRIu32" func=%u phys_port=%s dev_port=%lu %s %s",
|
||||
- domain, hotplug_slot, func, strempty(info->phys_port_name), dev_port,
|
||||
- special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_slot));
|
||||
- }
|
||||
+ if (hotplug_slot == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ s = names->pci_slot;
|
||||
+ l = sizeof(names->pci_slot);
|
||||
+ if (domain > 0)
|
||||
+ l = strpcpyf(&s, l, "P%u", domain);
|
||||
+ l = strpcpyf(&s, l, "s%"PRIu32, hotplug_slot);
|
||||
+ if (func > 0 || is_pci_multifunction(names->pcidev) > 0)
|
||||
+ l = strpcpyf(&s, l, "f%u", func);
|
||||
+ if (naming_scheme_has(NAMING_SR_IOV_R) && info->vf_representor_id >= 0)
|
||||
+ /* For VF representor append 'r<VF_NUM>' and not phys_port_name */
|
||||
+ l = strpcpyf(&s, l, "r%d", info->vf_representor_id);
|
||||
+ else if (!isempty(info->phys_port_name))
|
||||
+ l = strpcpyf(&s, l, "n%s", info->phys_port_name);
|
||||
+ else if (dev_port > 0)
|
||||
+ l = strpcpyf(&s, l, "d%lu", dev_port);
|
||||
+ if (l == 0)
|
||||
+ names->pci_slot[0] = '\0';
|
||||
+
|
||||
+ log_device_debug(dev, "Slot identifier: domain=%u slot=%"PRIu32" func=%u phys_port=%s dev_port=%lu %s %s",
|
||||
+ domain, hotplug_slot, func, strempty(info->phys_port_name), dev_port,
|
||||
+ special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_slot));
|
||||
|
||||
return 0;
|
||||
}
|
237
1023-udev-builtin-net_id-split-out-pci_get_hotplug_slot-a.patch
Normal file
237
1023-udev-builtin-net_id-split-out-pci_get_hotplug_slot-a.patch
Normal file
@ -0,0 +1,237 @@
|
||||
From 5685910315fb3b6c343db797fef9ef9d6e4ff01e Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Tue, 1 Aug 2023 03:27:33 +0900
|
||||
Subject: [PATCH] udev-builtin-net_id: split-out pci_get_hotplug_slot() and
|
||||
pci_get_hotplug_slot_from_address()
|
||||
|
||||
No functional changes, just refactoring.
|
||||
|
||||
(cherry picked from commit f1e3eaa730190a60fdb780be26ee331b8c811e34)
|
||||
|
||||
Related: RHEL-50103
|
||||
---
|
||||
src/udev/udev-builtin-net_id.c | 199 +++++++++++++++++++--------------
|
||||
1 file changed, 117 insertions(+), 82 deletions(-)
|
||||
|
||||
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||
index 5e76a894f7..16c9971876 100644
|
||||
--- a/src/udev/udev-builtin-net_id.c
|
||||
+++ b/src/udev/udev-builtin-net_id.c
|
||||
@@ -332,14 +332,121 @@ static int parse_hotplug_slot_from_function_id(sd_device *dev, int slots_dirfd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
- const char *sysname, *attr;
|
||||
+static int pci_get_hotplug_slot_from_address(
|
||||
+ sd_device *dev,
|
||||
+ sd_device *pci,
|
||||
+ DIR *dir,
|
||||
+ uint32_t *ret) {
|
||||
+
|
||||
+ const char *sysname;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(dev);
|
||||
+ assert(pci);
|
||||
+ assert(dir);
|
||||
+ assert(ret);
|
||||
+
|
||||
+ r = sd_device_get_sysname(dev, &sysname);
|
||||
+ if (r < 0)
|
||||
+ return log_device_debug_errno(dev, r, "Failed to get sysname: %m");
|
||||
+
|
||||
+ rewinddir(dir);
|
||||
+ FOREACH_DIRENT_ALL(de, dir, break) {
|
||||
+ _cleanup_free_ char *path = NULL;
|
||||
+ const char *address;
|
||||
+ uint32_t slot;
|
||||
+
|
||||
+ if (dot_or_dot_dot(de->d_name))
|
||||
+ continue;
|
||||
+
|
||||
+ if (de->d_type != DT_DIR)
|
||||
+ continue;
|
||||
+
|
||||
+ r = safe_atou32(de->d_name, &slot);
|
||||
+ if (r < 0 || slot <= 0)
|
||||
+ continue;
|
||||
+
|
||||
+ path = path_join("slots", de->d_name, "address");
|
||||
+ if (!path)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ if (sd_device_get_sysattr_value(pci, path, &address) < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* match slot address with device by stripping the function */
|
||||
+ if (!startswith(sysname, address))
|
||||
+ continue;
|
||||
+
|
||||
+ *ret = slot;
|
||||
+ return 1; /* found */
|
||||
+ }
|
||||
+
|
||||
+ *ret = 0;
|
||||
+ return 0; /* not found */
|
||||
+}
|
||||
+
|
||||
+static int pci_get_hotplug_slot(sd_device *dev, uint32_t *ret) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *pci = NULL;
|
||||
_cleanup_closedir_ DIR *dir = NULL;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(dev);
|
||||
+ assert(ret);
|
||||
+
|
||||
+ /* ACPI _SUN — slot user number */
|
||||
+ r = sd_device_new_from_subsystem_sysname(&pci, "subsystem", "pci");
|
||||
+ if (r < 0)
|
||||
+ return log_debug_errno(r, "Failed to create sd_device object for pci subsystem: %m");
|
||||
+
|
||||
+ r = device_opendir(pci, "slots", &dir);
|
||||
+ if (r < 0)
|
||||
+ return log_device_debug_errno(dev, r, "Cannot open 'slots' subdirectory: %m");
|
||||
+
|
||||
+ for (sd_device *slot_dev = dev; slot_dev; ) {
|
||||
+ uint32_t slot = 0; /* avoid false maybe-uninitialized warning */
|
||||
+
|
||||
+ r = parse_hotplug_slot_from_function_id(slot_dev, dirfd(dir), &slot);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ if (r > 0) {
|
||||
+ *ret = slot;
|
||||
+ return 1; /* domain should be ignored. */
|
||||
+ }
|
||||
+
|
||||
+ r = pci_get_hotplug_slot_from_address(slot_dev, pci, dir, &slot);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ if (r > 0) {
|
||||
+ /* We found the match between PCI device and slot. However, we won't use the slot
|
||||
+ * index if the device is a PCI bridge, because it can have other child devices that
|
||||
+ * will try to claim the same index and that would create name collision. */
|
||||
+ if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(slot_dev)) {
|
||||
+ if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT) && is_pci_multifunction(dev) <= 0)
|
||||
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ESTALE),
|
||||
+ "Not using slot information because the PCI device associated with "
|
||||
+ "the hotplug slot is a bridge and the PCI device has a single function.");
|
||||
+
|
||||
+ if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT))
|
||||
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ESTALE),
|
||||
+ "Not using slot information because the PCI device is a bridge.");
|
||||
+ }
|
||||
+
|
||||
+ *ret = slot;
|
||||
+ return 0; /* domain can be still used. */
|
||||
+ }
|
||||
+
|
||||
+ if (sd_device_get_parent_with_subsystem_devtype(slot_dev, "pci", NULL, &slot_dev) < 0)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
+static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
+ const char *sysname, *attr;
|
||||
unsigned domain, bus, slot, func;
|
||||
- sd_device *hotplug_slot_dev;
|
||||
unsigned long dev_port = 0;
|
||||
- uint32_t hotplug_slot = 0;
|
||||
+ uint32_t hotplug_slot = 0; /* avoid false maybe-uninitialized warning */
|
||||
size_t l;
|
||||
char *s;
|
||||
int r;
|
||||
@@ -410,85 +517,13 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
domain, bus, slot, func, strempty(info->phys_port_name), dev_port,
|
||||
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_path));
|
||||
|
||||
- /* ACPI _SUN — slot user number */
|
||||
- r = sd_device_new_from_subsystem_sysname(&pci, "subsystem", "pci");
|
||||
- if (r < 0)
|
||||
- return log_debug_errno(r, "sd_device_new_from_subsystem_sysname() failed: %m");
|
||||
-
|
||||
- r = device_opendir(pci, "slots", &dir);
|
||||
+ r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot);
|
||||
if (r < 0)
|
||||
- return log_device_debug_errno(dev, r, "Cannot access 'slots' subdirectory: %m");
|
||||
-
|
||||
- hotplug_slot_dev = names->pcidev;
|
||||
- while (hotplug_slot_dev) {
|
||||
- r = parse_hotplug_slot_from_function_id(hotplug_slot_dev, dirfd(dir), &hotplug_slot);
|
||||
- if (r < 0)
|
||||
- return 0;
|
||||
- if (r > 0) {
|
||||
- domain = 0; /* See comments in parse_hotplug_slot_from_function_id(). */
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- r = sd_device_get_sysname(hotplug_slot_dev, &sysname);
|
||||
- if (r < 0)
|
||||
- return log_device_debug_errno(hotplug_slot_dev, r, "Failed to get sysname: %m");
|
||||
-
|
||||
- FOREACH_DIRENT_ALL(de, dir, break) {
|
||||
- _cleanup_free_ char *path = NULL;
|
||||
- const char *address;
|
||||
- uint32_t i;
|
||||
-
|
||||
- if (dot_or_dot_dot(de->d_name))
|
||||
- continue;
|
||||
-
|
||||
- if (de->d_type != DT_DIR)
|
||||
- continue;
|
||||
-
|
||||
- r = safe_atou32(de->d_name, &i);
|
||||
- if (r < 0 || i <= 0)
|
||||
- continue;
|
||||
-
|
||||
- path = path_join("slots", de->d_name, "address");
|
||||
- if (!path)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- if (device_get_sysattr_value_filtered(pci, path, &address) < 0)
|
||||
- continue;
|
||||
-
|
||||
- /* match slot address with device by stripping the function */
|
||||
- if (!startswith(sysname, address))
|
||||
- continue;
|
||||
-
|
||||
- hotplug_slot = i;
|
||||
-
|
||||
- /* We found the match between PCI device and slot. However, we won't use the slot
|
||||
- * index if the device is a PCI bridge, because it can have other child devices that
|
||||
- * will try to claim the same index and that would create name collision. */
|
||||
- if (naming_scheme_has(NAMING_BRIDGE_NO_SLOT) && is_pci_bridge(hotplug_slot_dev)) {
|
||||
- if (naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT) && is_pci_multifunction(names->pcidev) <= 0) {
|
||||
- log_device_debug(dev,
|
||||
- "Not using slot information because the PCI device associated with "
|
||||
- "the hotplug slot is a bridge and the PCI device has a single function.");
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if (!naming_scheme_has(NAMING_BRIDGE_MULTIFUNCTION_SLOT)) {
|
||||
- log_device_debug(dev, "Not using slot information because the PCI device is a bridge.");
|
||||
- return 0;
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- break;
|
||||
- }
|
||||
- if (hotplug_slot > 0)
|
||||
- break;
|
||||
- if (sd_device_get_parent_with_subsystem_devtype(hotplug_slot_dev, "pci", NULL, &hotplug_slot_dev) < 0)
|
||||
- break;
|
||||
- rewinddir(dir);
|
||||
- }
|
||||
-
|
||||
- if (hotplug_slot == 0)
|
||||
- return 0;
|
||||
+ return r;
|
||||
+ if (r > 0)
|
||||
+ /* If the hotplug slot is found through the function ID, then drop the domain from the name.
|
||||
+ * See comments in parse_hotplug_slot_from_function_id(). */
|
||||
+ domain = 0;
|
||||
|
||||
s = names->pci_slot;
|
||||
l = sizeof(names->pci_slot);
|
170
1024-udev-builtin-net_id-use-firmware_node-sun-for-ID_NET.patch
Normal file
170
1024-udev-builtin-net_id-use-firmware_node-sun-for-ID_NET.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 7af151ca282d506a8e409a68b656f6d1cd2f13fb Mon Sep 17 00:00:00 2001
|
||||
From: Etienne Champetier <e.champetier@ateme.com>
|
||||
Date: Tue, 9 Jul 2024 11:53:50 -0400
|
||||
Subject: [PATCH] udev-builtin-net_id: use firmware_node/sun for
|
||||
ID_NET_NAME_SLOT
|
||||
|
||||
pci_get_hotplug_slot() has the following limitations:
|
||||
- if slots are not hotpluggable, they are not in /sys/bus/pci/slots.
|
||||
- the address at /sys/bus/pci/slots/X/addr doesn't contains the function part,
|
||||
so on some system, 2 different slots with different _SUN end up with the same
|
||||
hotplug_slot, leading to naming conflicts.
|
||||
- it tries all parent devices until it finds a slot number, which is incorrect,
|
||||
and what led to NAMING_BRIDGE_MULTIFUNCTION_SLOT being disabled.
|
||||
|
||||
The use of PCI hotplug to find the slot (ACPI _SUN) was introduced in
|
||||
https://github.com/systemd/systemd/commit/0035597a30d120f70df2dd7da3d6128fb8ba6051
|
||||
"udev: net_id - export PCI hotplug slot names" on 2012/11/26.
|
||||
At the same time on the kernel side we got
|
||||
https://github.com/torvalds/linux/commit/bb74ac23b10820d8722c3e1f4add9ef59e703f63
|
||||
"ACPI: create _SUN sysfs file" on 2012/11/16.
|
||||
|
||||
Using PCI hotplug was the only way at the time, but now 12 years later we can use
|
||||
firmware_node/sun sysfs file.
|
||||
Looking at a small selection of server HW, for HPE (Gen10 DL325), the _SUN is attached
|
||||
to the NIC device, whereas for Dell (R640/R6515/R6615) and Cisco (UCSC-C220-M5SX),
|
||||
the _SUN is on the first parent pcieport.
|
||||
|
||||
We still fallback to pci_get_hotplug_slot() to handle the s390 case and
|
||||
maybe some other coner cases (_SUN on grand parent device that is not a
|
||||
bridge ?).
|
||||
|
||||
(cherry picked from commit 0a4ecc54cb9f2d3418b970c51bfadb69c34ae9eb)
|
||||
|
||||
Resolves: RHEL-50103
|
||||
---
|
||||
man/systemd.net-naming-scheme.xml | 5 ++-
|
||||
src/shared/netif-naming-scheme.h | 3 +-
|
||||
src/udev/udev-builtin-net_id.c | 66 +++++++++++++++++++++++++++----
|
||||
3 files changed, 64 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
|
||||
index 83293e5636..c9a7e1e493 100644
|
||||
--- a/man/systemd.net-naming-scheme.xml
|
||||
+++ b/man/systemd.net-naming-scheme.xml
|
||||
@@ -510,9 +510,10 @@
|
||||
to distinguish between devices. However, name conflict can occur if these devices are not
|
||||
children of the same PCI bridge, e.g. there are multiple PCI bridges in the same slot.
|
||||
</para>
|
||||
+
|
||||
+ <para>PCI slot number is now read from <constant>firmware_node/sun</constant> sysfs file.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
-
|
||||
</variablelist>
|
||||
|
||||
<para>By default <constant>rhel-9.0</constant> is used.</para>
|
||||
@@ -666,7 +667,7 @@ ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
|
||||
</example>
|
||||
|
||||
<example>
|
||||
- <title>PCI Ethernet card in hotplug slot with firmware index number</title>
|
||||
+ <title>PCI Ethernet card in slot with firmware index number</title>
|
||||
|
||||
<programlisting># /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
|
||||
ID_NET_NAME_MAC=enx000000000466
|
||||
diff --git a/src/shared/netif-naming-scheme.h b/src/shared/netif-naming-scheme.h
|
||||
index 5bc071f8db..b1ac2e4320 100644
|
||||
--- a/src/shared/netif-naming-scheme.h
|
||||
+++ b/src/shared/netif-naming-scheme.h
|
||||
@@ -42,6 +42,7 @@ typedef enum NamingSchemeFlags {
|
||||
* This is disabled since rhel-9.5, as it seems not to work at least for some setups. See upstream issue #28929. */
|
||||
NAMING_DEVICETREE_ALIASES = 1 << 15, /* Generate names from devicetree aliases */
|
||||
NAMING_SR_IOV_R = 1 << 17, /* Use "r" suffix for SR-IOV VF representors */
|
||||
+ NAMING_FIRMWARE_NODE_SUN = 1 << 18, /* Use firmware_node/sun to get PCI slot number */
|
||||
|
||||
/* And now the masks that combine the features above */
|
||||
NAMING_V238 = 0,
|
||||
@@ -73,7 +74,7 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_RHEL_9_2 = NAMING_RHEL_9_0,
|
||||
NAMING_RHEL_9_3 = NAMING_RHEL_9_0 | NAMING_SR_IOV_R,
|
||||
NAMING_RHEL_9_4 = NAMING_RHEL_9_3,
|
||||
- NAMING_RHEL_9_5 = NAMING_RHEL_9_4 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT,
|
||||
+ NAMING_RHEL_9_5 = (NAMING_RHEL_9_4 & ~NAMING_BRIDGE_MULTIFUNCTION_SLOT) | NAMING_FIRMWARE_NODE_SUN,
|
||||
|
||||
EXTRA_NET_NAMING_SCHEMES
|
||||
|
||||
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
|
||||
index 16c9971876..291fb4ba36 100644
|
||||
--- a/src/udev/udev-builtin-net_id.c
|
||||
+++ b/src/udev/udev-builtin-net_id.c
|
||||
@@ -442,6 +442,51 @@ static int pci_get_hotplug_slot(sd_device *dev, uint32_t *ret) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
+static int get_device_firmware_node_sun(sd_device *dev, uint32_t *ret) {
|
||||
+ const char *attr;
|
||||
+ int r;
|
||||
+
|
||||
+ assert(dev);
|
||||
+ assert(ret);
|
||||
+
|
||||
+ r = device_get_sysattr_value_filtered(dev, "firmware_node/sun", &attr);
|
||||
+ if (r < 0)
|
||||
+ return log_device_debug_errno(dev, r, "Failed to read firmware_node/sun, ignoring: %m");
|
||||
+
|
||||
+ r = safe_atou32(attr, ret);
|
||||
+ if (r < 0)
|
||||
+ return log_device_warning_errno(dev, r, "Failed to parse firmware_node/sun '%s', ignoring: %m", attr);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int pci_get_slot_from_firmware_node_sun(sd_device *dev, uint32_t *ret) {
|
||||
+ int r;
|
||||
+ sd_device *slot_dev;
|
||||
+
|
||||
+ assert(dev);
|
||||
+ assert(ret);
|
||||
+
|
||||
+ /* Try getting the ACPI _SUN for the device */
|
||||
+ if (get_device_firmware_node_sun(dev, ret) >= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ r = sd_device_get_parent_with_subsystem_devtype(dev, "pci", NULL, &slot_dev);
|
||||
+ if (r < 0)
|
||||
+ return log_device_debug_errno(dev, r, "Failed to find pci parent, ignoring: %m");
|
||||
+
|
||||
+ if (is_pci_bridge(slot_dev) && is_pci_multifunction(dev) <= 0)
|
||||
+ return log_device_debug_errno(dev, SYNTHETIC_ERRNO(ESTALE),
|
||||
+ "Not using slot information because the parent pcieport "
|
||||
+ "is a bridge and the PCI device is not multifunction.");
|
||||
+
|
||||
+ /* Try getting the ACPI _SUN from the parent pcieport */
|
||||
+ if (get_device_firmware_node_sun(slot_dev, ret) >= 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
const char *sysname, *attr;
|
||||
unsigned domain, bus, slot, func;
|
||||
@@ -517,13 +562,20 @@ static int dev_pci_slot(sd_device *dev, const LinkInfo *info, NetNames *names) {
|
||||
domain, bus, slot, func, strempty(info->phys_port_name), dev_port,
|
||||
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), empty_to_na(names->pci_path));
|
||||
|
||||
- r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot);
|
||||
- if (r < 0)
|
||||
- return r;
|
||||
- if (r > 0)
|
||||
- /* If the hotplug slot is found through the function ID, then drop the domain from the name.
|
||||
- * See comments in parse_hotplug_slot_from_function_id(). */
|
||||
- domain = 0;
|
||||
+ if (naming_scheme_has(NAMING_FIRMWARE_NODE_SUN))
|
||||
+ r = pci_get_slot_from_firmware_node_sun(names->pcidev, &hotplug_slot);
|
||||
+ else
|
||||
+ r = -1;
|
||||
+ /* If we don't find a slot using firmware_node/sun, fallback to hotplug_slot */
|
||||
+ if (r < 0) {
|
||||
+ r = pci_get_hotplug_slot(names->pcidev, &hotplug_slot);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ if (r > 0)
|
||||
+ /* If the hotplug slot is found through the function ID, then drop the domain from the name.
|
||||
+ * See comments in parse_hotplug_slot_from_function_id(). */
|
||||
+ domain = 0;
|
||||
+ }
|
||||
|
||||
s = names->pci_slot;
|
||||
l = sizeof(names->pci_slot);
|
343
1025-Include-threads.h-if-possible-to-get-thread_local-de.patch
Normal file
343
1025-Include-threads.h-if-possible-to-get-thread_local-de.patch
Normal file
@ -0,0 +1,343 @@
|
||||
From 07e0a7f9a4f38e163082af202db0fbc795bc369c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= <crodriguez@owncloud.com>
|
||||
Date: Tue, 3 Jan 2023 17:52:08 +0000
|
||||
Subject: [PATCH] Include <threads.h> if possible to get thread_local
|
||||
definition
|
||||
|
||||
IN C23, thread_local is a reserved keyword and we shall therefore
|
||||
do nothing to redefine it. glibc has it defined for older standard
|
||||
version with the right conditions.
|
||||
|
||||
v2 by Yu Watanabe:
|
||||
Move the definition to missing_threads.h like the way we define e.g.
|
||||
missing syscalls or missing definitions, and include it by the users.
|
||||
|
||||
Co-authored-by: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
(cherry picked from commit 5545f336fd09148e8d9aa7f83ed19384deaf7a64)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
meson.build | 1 +
|
||||
src/basic/capability-util.c | 1 +
|
||||
src/basic/cgroup-util.c | 1 +
|
||||
src/basic/log.c | 1 +
|
||||
src/basic/macro.h | 14 --------------
|
||||
src/basic/memory-util.c | 1 +
|
||||
src/basic/missing_threads.h | 15 +++++++++++++++
|
||||
src/basic/process-util.c | 1 +
|
||||
src/basic/random-util.c | 1 +
|
||||
src/basic/signal-util.c | 1 +
|
||||
src/basic/time-util.c | 1 +
|
||||
src/basic/uid-alloc-range.c | 1 +
|
||||
src/basic/virt.c | 1 +
|
||||
src/libsystemd/sd-bus/sd-bus.c | 1 +
|
||||
src/libsystemd/sd-event/sd-event.c | 1 +
|
||||
src/libsystemd/sd-id128/sd-id128.c | 1 +
|
||||
src/libsystemd/sd-journal/journal-file.c | 1 +
|
||||
src/libsystemd/sd-resolve/sd-resolve.c | 1 +
|
||||
src/login/logind-inhibit.c | 1 +
|
||||
src/network/networkd-route-util.c | 1 +
|
||||
src/nss-systemd/nss-systemd.c | 1 +
|
||||
src/shared/cgroup-setup.c | 1 +
|
||||
src/shared/psi-util.c | 1 +
|
||||
23 files changed, 36 insertions(+), 14 deletions(-)
|
||||
create mode 100644 src/basic/missing_threads.h
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 274e43ba9e..cbde702211 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -745,6 +745,7 @@ foreach header : ['crypt.h',
|
||||
'linux/memfd.h',
|
||||
'linux/vm_sockets.h',
|
||||
'sys/auxv.h',
|
||||
+ 'threads.h',
|
||||
'valgrind/memcheck.h',
|
||||
'valgrind/valgrind.h',
|
||||
'linux/time_types.h',
|
||||
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c
|
||||
index fa74b5b9c6..df04d461ad 100644
|
||||
--- a/src/basic/capability-util.c
|
||||
+++ b/src/basic/capability-util.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "missing_prctl.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
|
||||
index b03cc70e2e..5266f93606 100644
|
||||
--- a/src/basic/cgroup-util.c
|
||||
+++ b/src/basic/cgroup-util.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "login-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing_magic.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "mkdir.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
diff --git a/src/basic/log.c b/src/basic/log.c
|
||||
index 39d08b0928..2e1642dc20 100644
|
||||
--- a/src/basic/log.c
|
||||
+++ b/src/basic/log.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "proc-cmdline.h"
|
||||
#include "process-util.h"
|
||||
diff --git a/src/basic/macro.h b/src/basic/macro.h
|
||||
index 6893a1ff32..c2934f9951 100644
|
||||
--- a/src/basic/macro.h
|
||||
+++ b/src/basic/macro.h
|
||||
@@ -319,20 +319,6 @@ static inline int __coverity_check_and_return__(int condition) {
|
||||
p != (typeof(p)) POINTER_MAX; \
|
||||
p = *(++_l))
|
||||
|
||||
-/* Define C11 thread_local attribute even on older gcc compiler
|
||||
- * version */
|
||||
-#ifndef thread_local
|
||||
-/*
|
||||
- * Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
|
||||
- * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769
|
||||
- */
|
||||
-#if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
|
||||
-#define thread_local _Thread_local
|
||||
-#else
|
||||
-#define thread_local __thread
|
||||
-#endif
|
||||
-#endif
|
||||
-
|
||||
#define _FOREACH_ARRAY(i, array, num, m, end) \
|
||||
for (typeof(array[0]) *i = (array), *end = ({ \
|
||||
typeof(num) m = (num); \
|
||||
diff --git a/src/basic/memory-util.c b/src/basic/memory-util.c
|
||||
index c4f54c7b4e..fcedae2d41 100644
|
||||
--- a/src/basic/memory-util.c
|
||||
+++ b/src/basic/memory-util.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "memory-util.h"
|
||||
+#include "missing_threads.h"
|
||||
|
||||
size_t page_size(void) {
|
||||
static thread_local size_t pgsz = 0;
|
||||
diff --git a/src/basic/missing_threads.h b/src/basic/missing_threads.h
|
||||
new file mode 100644
|
||||
index 0000000000..fb3b72249b
|
||||
--- /dev/null
|
||||
+++ b/src/basic/missing_threads.h
|
||||
@@ -0,0 +1,15 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+#pragma once
|
||||
+
|
||||
+/* If threads.h doesn't exist, then define our own thread_local to match C11's thread_local. */
|
||||
+#if HAVE_THREADS_H
|
||||
+# include <threads.h>
|
||||
+#elif !(defined(thread_local))
|
||||
+/* Don't break on glibc < 2.16 that doesn't define __STDC_NO_THREADS__
|
||||
+ * see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53769 */
|
||||
+# if __STDC_VERSION__ >= 201112L && !(defined(__STDC_NO_THREADS__) || (defined(__GNU_LIBRARY__) && __GLIBC__ == 2 && __GLIBC_MINOR__ < 16))
|
||||
+# define thread_local _Thread_local
|
||||
+# else
|
||||
+# define thread_local __thread
|
||||
+# endif
|
||||
+#endif
|
||||
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||
index 0213f5913f..65367768c9 100644
|
||||
--- a/src/basic/process-util.c
|
||||
+++ b/src/basic/process-util.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "memory-util.h"
|
||||
#include "missing_sched.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "namespace-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
|
||||
index d8734cc7d0..200a914196 100644
|
||||
--- a/src/basic/random-util.c
|
||||
+++ b/src/basic/random-util.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "io-util.h"
|
||||
#include "missing_random.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "random-util.h"
|
||||
#include "sha256.h"
|
||||
diff --git a/src/basic/signal-util.c b/src/basic/signal-util.c
|
||||
index b61c18b2de..fdbe7f43ac 100644
|
||||
--- a/src/basic/signal-util.c
|
||||
+++ b/src/basic/signal-util.c
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "errno-util.h"
|
||||
#include "macro.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "stdio-util.h"
|
||||
diff --git a/src/basic/time-util.c b/src/basic/time-util.c
|
||||
index 71b2f67350..f5e10bba1a 100644
|
||||
--- a/src/basic/time-util.c
|
||||
+++ b/src/basic/time-util.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "io-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "missing_timerfd.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
diff --git a/src/basic/uid-alloc-range.c b/src/basic/uid-alloc-range.c
|
||||
index 1b6d761a66..8b3741e438 100644
|
||||
--- a/src/basic/uid-alloc-range.c
|
||||
+++ b/src/basic/uid-alloc-range.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "chase-symlinks.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "string-util.h"
|
||||
#include "uid-alloc-range.h"
|
||||
#include "user-util.h"
|
||||
diff --git a/src/basic/virt.c b/src/basic/virt.c
|
||||
index 710f0372ea..2a8e696a45 100644
|
||||
--- a/src/basic/virt.c
|
||||
+++ b/src/basic/virt.c
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "macro.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "process-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-table.h"
|
||||
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||
index c3a1bae295..10efe53a25 100644
|
||||
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
|
||||
index cd73cd8bfd..165abfc314 100644
|
||||
--- a/src/libsystemd/sd-event/sd-event.c
|
||||
+++ b/src/libsystemd/sd-event/sd-event.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "prioq.h"
|
||||
#include "process-util.h"
|
||||
#include "set.h"
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index ec53617fce..15177bc3c9 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "io-util.h"
|
||||
#include "macro.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "random-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "user-util.h"
|
||||
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c
|
||||
index 2b66b3caed..e8c9d4dc3d 100644
|
||||
--- a/src/libsystemd/sd-journal/journal-file.c
|
||||
+++ b/src/libsystemd/sd-journal/journal-file.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "journal-file.h"
|
||||
#include "lookup3.h"
|
||||
#include "memory-util.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "path-util.h"
|
||||
#include "random-util.h"
|
||||
#include "set.h"
|
||||
diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c
|
||||
index 5362ec0fa8..ba88168f02 100644
|
||||
--- a/src/libsystemd/sd-resolve/sd-resolve.c
|
||||
+++ b/src/libsystemd/sd-resolve/sd-resolve.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "list.h"
|
||||
#include "memory-util.h"
|
||||
#include "missing_syscall.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "process-util.h"
|
||||
#include "resolve-private.h"
|
||||
#include "socket-util.h"
|
||||
diff --git a/src/login/logind-inhibit.c b/src/login/logind-inhibit.c
|
||||
index 16612ddf18..26caa2b5b5 100644
|
||||
--- a/src/login/logind-inhibit.c
|
||||
+++ b/src/login/logind-inhibit.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "io-util.h"
|
||||
#include "logind-dbus.h"
|
||||
#include "logind-inhibit.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
diff --git a/src/network/networkd-route-util.c b/src/network/networkd-route-util.c
|
||||
index 0366382093..d461aadd65 100644
|
||||
--- a/src/network/networkd-route-util.c
|
||||
+++ b/src/network/networkd-route-util.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
diff --git a/src/nss-systemd/nss-systemd.c b/src/nss-systemd/nss-systemd.c
|
||||
index 75d749e736..1d6e25399f 100644
|
||||
--- a/src/nss-systemd/nss-systemd.c
|
||||
+++ b/src/nss-systemd/nss-systemd.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "nss-systemd.h"
|
||||
#include "nss-util.h"
|
||||
#include "pthread-util.h"
|
||||
diff --git a/src/shared/cgroup-setup.c b/src/shared/cgroup-setup.c
|
||||
index 2ea83f05d3..65be851014 100644
|
||||
--- a/src/shared/cgroup-setup.c
|
||||
+++ b/src/shared/cgroup-setup.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "fs-util.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "mkdir.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
diff --git a/src/shared/psi-util.c b/src/shared/psi-util.c
|
||||
index 8bdd0d4a85..c91bbc3013 100644
|
||||
--- a/src/shared/psi-util.c
|
||||
+++ b/src/shared/psi-util.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
+#include "missing_threads.h"
|
||||
#include "parse-util.h"
|
||||
#include "psi-util.h"
|
||||
#include "string-util.h"
|
395
1026-add-APIs-for-detecting-confidential-virtualization.patch
Normal file
395
1026-add-APIs-for-detecting-confidential-virtualization.patch
Normal file
@ -0,0 +1,395 @@
|
||||
From 945dd3348084b1cc71721e9ed35041ef37689e49 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 9 Jun 2023 15:37:18 +0100
|
||||
Subject: [PATCH] add APIs for detecting confidential virtualization
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This code uses various CPUID checks to be able to identify
|
||||
|
||||
* AMD SEV
|
||||
* AMD SEV-ES
|
||||
* AMD SEV-SNP
|
||||
* Intel TDX
|
||||
|
||||
On HyperV/Azure, it has special checks for detecting SEV-SNP
|
||||
since the normal CPUID is blocked.
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit a577a61625b979f0198e1ed9a527ba48fd78be13)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
src/basic/confidential-virt.c | 293 ++++++++++++++++++++++++++++++++++
|
||||
src/basic/confidential-virt.h | 25 +++
|
||||
src/basic/meson.build | 2 +
|
||||
src/test/test-tables.c | 2 +
|
||||
4 files changed, 322 insertions(+)
|
||||
create mode 100644 src/basic/confidential-virt.c
|
||||
create mode 100644 src/basic/confidential-virt.h
|
||||
|
||||
diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c
|
||||
new file mode 100644
|
||||
index 0000000000..3d4e9eac33
|
||||
--- /dev/null
|
||||
+++ b/src/basic/confidential-virt.c
|
||||
@@ -0,0 +1,293 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+
|
||||
+#if defined(__i386__) || defined(__x86_64__)
|
||||
+#include <cpuid.h>
|
||||
+#endif
|
||||
+#include <errno.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <stdint.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <unistd.h>
|
||||
+
|
||||
+#include "confidential-virt.h"
|
||||
+#include "fd-util.h"
|
||||
+#include "missing_threads.h"
|
||||
+#include "string-table.h"
|
||||
+#include "utf8.h"
|
||||
+
|
||||
+#define CPUID_PROCESSOR_INFO_AND_FEATURE_BITS UINT32_C(0x1)
|
||||
+
|
||||
+/*
|
||||
+ * 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 UINT32_C(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 UINT32_C(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 UINT32_C(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 UINT32_C(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 UINT32_C(0x40000000)
|
||||
+
|
||||
+#define CPUID_HYPERV_FEATURES UINT32_C(0x40000003)
|
||||
+
|
||||
+#define CPUID_HYPERV_ISOLATION_CONFIG UINT32_C(0x4000000C)
|
||||
+
|
||||
+#define CPUID_HYPERV_MIN UINT32_C(0x40000005)
|
||||
+#define CPUID_HYPERV_MAX UINT32_C(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 (UINT32_C(1) << 31)
|
||||
+
|
||||
+/* Linux include/asm-generic/hyperv-tlfs.h */
|
||||
+#define CPUID_HYPERV_CPU_MANAGEMENT (UINT32_C(1) << 12) /* root partition */
|
||||
+#define CPUID_HYPERV_ISOLATION (UINT32_C(1) << 22) /* confidential VM partition */
|
||||
+
|
||||
+#define CPUID_HYPERV_ISOLATION_TYPE_MASK UINT32_C(0xf)
|
||||
+#define CPUID_HYPERV_ISOLATION_TYPE_SNP 2
|
||||
+
|
||||
+#define EAX_SEV (UINT32_C(1) << 1)
|
||||
+#define MSR_SEV (UINT64_C(1) << 0)
|
||||
+#define MSR_SEV_ES (UINT64_C(1) << 1)
|
||||
+#define MSR_SEV_SNP (UINT64_C(1) << 2)
|
||||
+
|
||||
+#if defined(__x86_64__)
|
||||
+
|
||||
+static void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) {
|
||||
+ log_debug("CPUID func %" PRIx32 " %" PRIx32, *eax, *ecx);
|
||||
+ __cpuid_count(*eax, *ecx, *eax, *ebx, *ecx, *edx);
|
||||
+ log_debug("CPUID result %" PRIx32 " %" PRIx32 " %" PRIx32 " %" PRIx32, *eax, *ebx, *ecx, *edx);
|
||||
+}
|
||||
+
|
||||
+static uint32_t cpuid_leaf(uint32_t eax, char ret_sig[static 13], bool swapped) {
|
||||
+ /* zero-init as some queries explicitly require subleaf == 0 */
|
||||
+ uint32_t sig[3] = {};
|
||||
+
|
||||
+ if (swapped)
|
||||
+ cpuid(&eax, &sig[0], &sig[2], &sig[1]);
|
||||
+ else
|
||||
+ cpuid(&eax, &sig[0], &sig[1], &sig[2]);
|
||||
+ memcpy(ret_sig, sig, sizeof(sig));
|
||||
+ ret_sig[12] = 0; /* \0-terminate the string to make string comparison possible */
|
||||
+
|
||||
+ /* In some CI tests ret_sig doesn't contain valid UTF8 and prints garbage to the console */
|
||||
+ log_debug("CPUID sig '%s'", strna(utf8_is_valid(ret_sig)));
|
||||
+
|
||||
+ return eax;
|
||||
+}
|
||||
+
|
||||
+#define MSR_DEVICE "/dev/cpu/0/msr"
|
||||
+
|
||||
+static uint64_t msr(uint64_t index) {
|
||||
+ uint64_t ret;
|
||||
+ ssize_t rv;
|
||||
+ _cleanup_close_ int fd = -EBADF;
|
||||
+
|
||||
+ fd = open(MSR_DEVICE, O_RDONLY|O_CLOEXEC);
|
||||
+ if (fd < 0) {
|
||||
+ log_debug_errno(errno,
|
||||
+ "Cannot open MSR device %s (index %" PRIu64 "), ignoring: %m",
|
||||
+ MSR_DEVICE,
|
||||
+ index);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ rv = pread(fd, &ret, sizeof(ret), index);
|
||||
+ if (rv < 0) {
|
||||
+ log_debug_errno(errno,
|
||||
+ "Cannot read MSR device %s (index %" PRIu64 "), ignoring: %m",
|
||||
+ MSR_DEVICE,
|
||||
+ index);
|
||||
+ return 0;
|
||||
+ } else if (rv != sizeof(ret)) {
|
||||
+ log_debug("Short read %ld bytes from MSR device %s (index %" PRIu64 "), ignoring",
|
||||
+ rv,
|
||||
+ MSR_DEVICE,
|
||||
+ index);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ log_debug("MSR %" PRIu64 " result %" PRIu64 "", index, ret);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static bool detect_hyperv_sev(void) {
|
||||
+ uint32_t eax, ebx, ecx, edx, feat;
|
||||
+ char sig[13] = {};
|
||||
+
|
||||
+ 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;
|
||||
+
|
||||
+ log_debug("CPUID is on hyperv");
|
||||
+ 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 ConfidentialVirtualization detect_sev(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 CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+
|
||||
+ 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 trying some HyperV
|
||||
+ * specific CPUID checks.
|
||||
+ */
|
||||
+ if (!(eax & EAX_SEV)) {
|
||||
+ log_debug("No sev in CPUID, trying hyperv CPUID");
|
||||
+
|
||||
+ if (detect_hyperv_sev())
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_SEV_SNP;
|
||||
+
|
||||
+ log_debug("No hyperv CPUID");
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+ }
|
||||
+
|
||||
+ 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 & MSR_SEV_SNP)
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_SEV_SNP;
|
||||
+ if (msrval & MSR_SEV_ES)
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_SEV_ES;
|
||||
+ if (msrval & MSR_SEV)
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_SEV;
|
||||
+
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+}
|
||||
+
|
||||
+static ConfidentialVirtualization detect_tdx(void) {
|
||||
+ uint32_t eax, ebx, ecx, edx;
|
||||
+ char sig[13] = {};
|
||||
+
|
||||
+ eax = CPUID_GET_HIGHEST_FUNCTION;
|
||||
+ ebx = ecx = edx = 0;
|
||||
+
|
||||
+ cpuid(&eax, &ebx, &ecx, &edx);
|
||||
+
|
||||
+ if (eax < CPUID_INTEL_TDX_ENUMERATION)
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+
|
||||
+ cpuid_leaf(CPUID_INTEL_TDX_ENUMERATION, sig, true);
|
||||
+
|
||||
+ if (memcmp(sig, CPUID_SIG_INTEL_TDX, sizeof(sig)) == 0)
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_TDX;
|
||||
+
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+}
|
||||
+
|
||||
+static bool detect_hypervisor(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;
|
||||
+
|
||||
+ log_debug("CPUID is hypervisor: %s", yes_no(is_hv));
|
||||
+ return is_hv;
|
||||
+}
|
||||
+
|
||||
+ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
+ static thread_local ConfidentialVirtualization cached_found = _CONFIDENTIAL_VIRTUALIZATION_INVALID;
|
||||
+ char sig[13] = {};
|
||||
+ ConfidentialVirtualization cv = CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+
|
||||
+ if (cached_found >= 0)
|
||||
+ return cached_found;
|
||||
+
|
||||
+ /* Skip everything on bare metal */
|
||||
+ if (detect_hypervisor()) {
|
||||
+ cpuid_leaf(0, sig, true);
|
||||
+
|
||||
+ if (memcmp(sig, CPUID_SIG_AMD, sizeof(sig)) == 0)
|
||||
+ cv = detect_sev();
|
||||
+ else if (memcmp(sig, CPUID_SIG_INTEL, sizeof(sig)) == 0)
|
||||
+ cv = detect_tdx();
|
||||
+ }
|
||||
+
|
||||
+ cached_found = cv;
|
||||
+ return cv;
|
||||
+}
|
||||
+#else /* ! x86_64 */
|
||||
+ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
+ log_debug("No confidential virtualization detection on this architecture");
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+}
|
||||
+#endif /* ! x86_64 */
|
||||
+
|
||||
+static const char *const confidential_virtualization_table[_CONFIDENTIAL_VIRTUALIZATION_MAX] = {
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_NONE] = "none",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV_ES] = "sev-es",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV_SNP] = "sev-snp",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_TDX] = "tdx",
|
||||
+};
|
||||
+
|
||||
+DEFINE_STRING_TABLE_LOOKUP(confidential_virtualization, ConfidentialVirtualization);
|
||||
diff --git a/src/basic/confidential-virt.h b/src/basic/confidential-virt.h
|
||||
new file mode 100644
|
||||
index 0000000000..c02f3b2321
|
||||
--- /dev/null
|
||||
+++ b/src/basic/confidential-virt.h
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+#pragma once
|
||||
+
|
||||
+#include <stdbool.h>
|
||||
+
|
||||
+#include "errno-list.h"
|
||||
+#include "macro.h"
|
||||
+
|
||||
+typedef enum ConfidentialVirtualization {
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_NONE = 0,
|
||||
+
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_SEV,
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_SEV_ES,
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_SEV_SNP,
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_TDX,
|
||||
+
|
||||
+ _CONFIDENTIAL_VIRTUALIZATION_MAX,
|
||||
+ _CONFIDENTIAL_VIRTUALIZATION_INVALID = -EINVAL,
|
||||
+ _CONFIDENTIAL_VIRTUALIZATION_ERRNO_MAX = -ERRNO_MAX, /* ensure full range of errno fits into this enum */
|
||||
+} ConfidentialVirtualization;
|
||||
+
|
||||
+ConfidentialVirtualization detect_confidential_virtualization(void);
|
||||
+
|
||||
+const char *confidential_virtualization_to_string(ConfidentialVirtualization v) _const_;
|
||||
+ConfidentialVirtualization confidential_virtualization_from_string(const char *s) _pure_;
|
||||
diff --git a/src/basic/meson.build b/src/basic/meson.build
|
||||
index c0f0b07418..11053a5ecd 100644
|
||||
--- a/src/basic/meson.build
|
||||
+++ b/src/basic/meson.build
|
||||
@@ -31,6 +31,8 @@ basic_sources = files(
|
||||
'chattr-util.h',
|
||||
'conf-files.c',
|
||||
'conf-files.h',
|
||||
+ 'confidential-virt.c',
|
||||
+ 'confidential-virt.h',
|
||||
'def.h',
|
||||
'devnum-util.c',
|
||||
'devnum-util.h',
|
||||
diff --git a/src/test/test-tables.c b/src/test/test-tables.c
|
||||
index 30ca1871cb..d47d3d75cc 100644
|
||||
--- a/src/test/test-tables.c
|
||||
+++ b/src/test/test-tables.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "cgroup-util.h"
|
||||
#include "compress.h"
|
||||
#include "condition.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "device-private.h"
|
||||
#include "device.h"
|
||||
#include "discover-image.h"
|
||||
@@ -50,6 +51,7 @@ int main(int argc, char **argv) {
|
||||
test_table(collect_mode, COLLECT_MODE);
|
||||
test_table(condition_result, CONDITION_RESULT);
|
||||
test_table(condition_type, CONDITION_TYPE);
|
||||
+ test_table(confidential_virtualization, CONFIDENTIAL_VIRTUALIZATION);
|
||||
test_table(device_action, SD_DEVICE_ACTION);
|
||||
test_table(device_state, DEVICE_STATE);
|
||||
test_table(dns_over_tls_mode, DNS_OVER_TLS_MODE);
|
134
1027-detect-virt-add-cvm-option.patch
Normal file
134
1027-detect-virt-add-cvm-option.patch
Normal file
@ -0,0 +1,134 @@
|
||||
From dfd60d406727c03e5d6390639361aeb4f8a5849a Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 30 Jun 2023 19:07:29 +0100
|
||||
Subject: [PATCH] detect-virt: add --cvm option
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The --cvm option detects whether the OS is running inside a confidential
|
||||
virtual machine.
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 5e0c61f64d22ed9d4ae53ed94209ed4be25feb30)
|
||||
|
||||
Resolves: RHEL-50651
|
||||
---
|
||||
man/systemd-detect-virt.xml | 10 ++++++++++
|
||||
shell-completion/bash/systemd-detect-virt | 2 +-
|
||||
src/detect-virt/detect-virt.c | 18 ++++++++++++++++++
|
||||
3 files changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
|
||||
index a8c089d0b5..9b24f061bb 100644
|
||||
--- a/man/systemd-detect-virt.xml
|
||||
+++ b/man/systemd-detect-virt.xml
|
||||
@@ -252,6 +252,16 @@
|
||||
for more information.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><option>--cvm</option></term>
|
||||
+
|
||||
+ <listitem><para>Detect whether invoked in a confidential virtual machine.
|
||||
+ The result of this detection may be used to disable features that should
|
||||
+ not be used in confidential VMs. It must not be used to release security
|
||||
+ sensitive information. The latter must only be released after attestation
|
||||
+ of the confidential environment.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<varlistentry>
|
||||
<term><option>-q</option></term>
|
||||
<term><option>--quiet</option></term>
|
||||
diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt
|
||||
index 05e44903e0..e67570e674 100644
|
||||
--- a/shell-completion/bash/systemd-detect-virt
|
||||
+++ b/shell-completion/bash/systemd-detect-virt
|
||||
@@ -28,7 +28,7 @@ _systemd_detect_virt() {
|
||||
local i verb comps
|
||||
|
||||
local -A OPTS=(
|
||||
- [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet
|
||||
+ [STANDALONE]='-h --help --version -c --container -v --vm -q --quiet --cvm
|
||||
--private-users'
|
||||
)
|
||||
|
||||
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
|
||||
index af2a58b78d..6b470642dd 100644
|
||||
--- a/src/detect-virt/detect-virt.c
|
||||
+++ b/src/detect-virt/detect-virt.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "main-func.h"
|
||||
#include "pretty-print.h"
|
||||
#include "string-table.h"
|
||||
@@ -19,6 +20,7 @@ static enum {
|
||||
ONLY_CONTAINER,
|
||||
ONLY_CHROOT,
|
||||
ONLY_PRIVATE_USERS,
|
||||
+ ONLY_CVM,
|
||||
} arg_mode = ANY_VIRTUALIZATION;
|
||||
|
||||
static int help(void) {
|
||||
@@ -37,6 +39,7 @@ static int help(void) {
|
||||
" -v --vm Only detect whether we are run in a VM\n"
|
||||
" -r --chroot Detect whether we are run in a chroot() environment\n"
|
||||
" --private-users Only detect whether we are running in a user namespace\n"
|
||||
+ " --cvm Only detect whether we are run in a confidential VM\n"
|
||||
" -q --quiet Don't output anything, just set return value\n"
|
||||
" --list List all known and detectable types of virtualization\n"
|
||||
"\nSee the %s for details.\n",
|
||||
@@ -52,6 +55,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_PRIVATE_USERS,
|
||||
ARG_LIST,
|
||||
+ ARG_CVM,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -62,6 +66,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "chroot", no_argument, NULL, 'r' },
|
||||
{ "private-users", no_argument, NULL, ARG_PRIVATE_USERS },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
+ { "cvm", no_argument, NULL, ARG_CVM },
|
||||
{ "list", no_argument, NULL, ARG_LIST },
|
||||
{}
|
||||
};
|
||||
@@ -105,6 +110,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
DUMP_STRING_TABLE(virtualization, Virtualization, _VIRTUALIZATION_MAX);
|
||||
return 0;
|
||||
|
||||
+ case ARG_CVM:
|
||||
+ arg_mode = ONLY_CVM;
|
||||
+ return 1;
|
||||
+
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@@ -122,6 +131,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
Virtualization v;
|
||||
+ ConfidentialVirtualization c;
|
||||
int r;
|
||||
|
||||
/* This is mostly intended to be used for scripts which want
|
||||
@@ -159,6 +169,14 @@ static int run(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to check for user namespace: %m");
|
||||
return !r;
|
||||
|
||||
+ case ONLY_CVM:
|
||||
+ c = detect_confidential_virtualization();
|
||||
+ if (c < 0)
|
||||
+ return log_error_errno(c, "Failed to check for confidential virtualization: %m");
|
||||
+ if (!arg_quiet)
|
||||
+ puts(confidential_virtualization_to_string(c));
|
||||
+ return c == CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+
|
||||
case ANY_VIRTUALIZATION:
|
||||
default:
|
||||
v = detect_virtualization();
|
92
1028-detect-virt-add-list-cvm-option.patch
Normal file
92
1028-detect-virt-add-list-cvm-option.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From a7d640fa28095c246b4c648bc6052fd4d091f268 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 30 Jun 2023 19:07:29 +0100
|
||||
Subject: [PATCH] detect-virt: add --list-cvm option
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The --list-cvm option reports the known types of confidential virtualization
|
||||
technology that can be detected.
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit f460fec91524b6171183e70f03e10ab025bd1f03)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/systemd-detect-virt.xml | 6 ++++++
|
||||
shell-completion/bash/systemd-detect-virt | 2 +-
|
||||
src/detect-virt/detect-virt.c | 8 ++++++++
|
||||
3 files changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
|
||||
index 9b24f061bb..5aaff839a4 100644
|
||||
--- a/man/systemd-detect-virt.xml
|
||||
+++ b/man/systemd-detect-virt.xml
|
||||
@@ -276,6 +276,12 @@
|
||||
<listitem><para>Output all currently known and detectable container and VM environments.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><option>--list-cvm</option></term>
|
||||
+
|
||||
+ <listitem><para>Output all currently known and detectable confidential virtualization technologies.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
diff --git a/shell-completion/bash/systemd-detect-virt b/shell-completion/bash/systemd-detect-virt
|
||||
index e67570e674..9ade2af220 100644
|
||||
--- a/shell-completion/bash/systemd-detect-virt
|
||||
+++ b/shell-completion/bash/systemd-detect-virt
|
||||
@@ -29,7 +29,7 @@ _systemd_detect_virt() {
|
||||
|
||||
local -A OPTS=(
|
||||
[STANDALONE]='-h --help --version -c --container -v --vm -q --quiet --cvm
|
||||
- --private-users'
|
||||
+ --private-users --list --list-cvm'
|
||||
)
|
||||
|
||||
_init_completion || return
|
||||
diff --git a/src/detect-virt/detect-virt.c b/src/detect-virt/detect-virt.c
|
||||
index 6b470642dd..9732e3731f 100644
|
||||
--- a/src/detect-virt/detect-virt.c
|
||||
+++ b/src/detect-virt/detect-virt.c
|
||||
@@ -42,6 +42,8 @@ static int help(void) {
|
||||
" --cvm Only detect whether we are run in a confidential VM\n"
|
||||
" -q --quiet Don't output anything, just set return value\n"
|
||||
" --list List all known and detectable types of virtualization\n"
|
||||
+ " --list-cvm List all known and detectable types of confidential \n"
|
||||
+ " virtualization\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
link);
|
||||
@@ -56,6 +58,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_PRIVATE_USERS,
|
||||
ARG_LIST,
|
||||
ARG_CVM,
|
||||
+ ARG_LIST_CVM,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@@ -68,6 +71,7 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "cvm", no_argument, NULL, ARG_CVM },
|
||||
{ "list", no_argument, NULL, ARG_LIST },
|
||||
+ { "list-cvm", no_argument, NULL, ARG_LIST_CVM },
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -114,6 +118,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_mode = ONLY_CVM;
|
||||
return 1;
|
||||
|
||||
+ case ARG_LIST_CVM:
|
||||
+ DUMP_STRING_TABLE(confidential_virtualization, ConfidentialVirtualization, _CONFIDENTIAL_VIRTUALIZATION_MAX);
|
||||
+ return 0;
|
||||
+
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
92
1029-unit-add-cvm-option-for-ConditionSecurity.patch
Normal file
92
1029-unit-add-cvm-option-for-ConditionSecurity.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From 00cb3bb597a6fb8bf825b79c96945bd051669080 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 30 Jun 2023 19:01:17 +0100
|
||||
Subject: [PATCH] unit: add "cvm" option for ConditionSecurity
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The "cvm" flag indicates whether the OS is running inside a confidential
|
||||
virtual machine.
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 95d043b1595e7684163714aae46822b18cef0f65)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/systemd.unit.xml | 4 ++--
|
||||
src/shared/condition.c | 3 +++
|
||||
src/test/test-condition.c | 9 +++++++++
|
||||
3 files changed, 14 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
|
||||
index d41909bcc6..afa4aea5c9 100644
|
||||
--- a/man/systemd.unit.xml
|
||||
+++ b/man/systemd.unit.xml
|
||||
@@ -1393,8 +1393,8 @@
|
||||
security technology is enabled on the system. Currently, the recognized values are
|
||||
<literal>selinux</literal>, <literal>apparmor</literal>, <literal>tomoyo</literal>,
|
||||
<literal>ima</literal>, <literal>smack</literal>, <literal>audit</literal>,
|
||||
- <literal>uefi-secureboot</literal> and <literal>tpm2</literal>. The test may be negated by prepending
|
||||
- an exclamation mark.</para>
|
||||
+ <literal>uefi-secureboot</literal>, <literal>tpm2</literal> and <literal>cvm</literal>.
|
||||
+ The test may be negated by prepending an exclamation mark.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/shared/condition.c b/src/shared/condition.c
|
||||
index a23d6a3e45..e736b78d8a 100644
|
||||
--- a/src/shared/condition.c
|
||||
+++ b/src/shared/condition.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "cgroup-util.h"
|
||||
#include "compare-operator.h"
|
||||
#include "condition.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "creds-util.h"
|
||||
#include "efi-api.h"
|
||||
@@ -694,6 +695,8 @@ static int condition_test_security(Condition *c, char **env) {
|
||||
return is_efi_secure_boot();
|
||||
if (streq(c->parameter, "tpm2"))
|
||||
return has_tpm2();
|
||||
+ if (streq(c->parameter, "cvm"))
|
||||
+ return detect_confidential_virtualization() > 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
|
||||
index b16e8047c6..0894c4bfdb 100644
|
||||
--- a/src/test/test-condition.c
|
||||
+++ b/src/test/test-condition.c
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "audit-util.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "condition.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "efi-loader.h"
|
||||
#include "env-util.h"
|
||||
@@ -784,6 +785,12 @@ TEST(condition_test_security) {
|
||||
assert_se(condition);
|
||||
assert_se(condition_test(condition, environ) == is_efi_secure_boot());
|
||||
condition_free(condition);
|
||||
+
|
||||
+ condition = condition_new(CONDITION_SECURITY, "cvm", false, false);
|
||||
+ assert_se(condition);
|
||||
+ assert_se(condition_test(condition, environ) ==
|
||||
+ (detect_confidential_virtualization() != CONFIDENTIAL_VIRTUALIZATION_NONE));
|
||||
+ condition_free(condition);
|
||||
}
|
||||
|
||||
TEST(print_securities) {
|
||||
@@ -795,6 +802,8 @@ TEST(print_securities) {
|
||||
log_info("SMACK: %s", yes_no(mac_smack_use()));
|
||||
log_info("Audit: %s", yes_no(use_audit()));
|
||||
log_info("UEFI secure boot: %s", yes_no(is_efi_secure_boot()));
|
||||
+ log_info("Confidential VM: %s", yes_no
|
||||
+ (detect_confidential_virtualization() != CONFIDENTIAL_VIRTUALIZATION_NONE));
|
||||
log_info("-------------------------------------------");
|
||||
}
|
||||
|
105
1030-dbus-add-ConfidentialVirtualization-property-to-mana.patch
Normal file
105
1030-dbus-add-ConfidentialVirtualization-property-to-mana.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 9ebd1d71a61e4e036e65452c1c04516ea58d74b7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 3 Jul 2023 09:53:43 +0100
|
||||
Subject: [PATCH] dbus: add 'ConfidentialVirtualization' property to manager
|
||||
object
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This property reports whether the system is running inside a confidential
|
||||
virtual machine.
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 1257274ad8eb0790bc3b56ba68b114c5e1e24713)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/org.freedesktop.systemd1.xml | 10 ++++++++++
|
||||
src/core/dbus-manager.c | 23 +++++++++++++++++++++++
|
||||
2 files changed, 33 insertions(+)
|
||||
|
||||
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
|
||||
index 7ee649f6a7..78781b6ed3 100644
|
||||
--- a/man/org.freedesktop.systemd1.xml
|
||||
+++ b/man/org.freedesktop.systemd1.xml
|
||||
@@ -293,6 +293,8 @@ node /org/freedesktop/systemd1 {
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s Virtualization = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
+ readonly s ConfidentialVirtualization = '...';
|
||||
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s Architecture = '...';
|
||||
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
|
||||
readonly s Tainted = '...';
|
||||
@@ -974,6 +976,8 @@ node /org/freedesktop/systemd1 {
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Virtualization"/>
|
||||
|
||||
+ <variablelist class="dbus-property" generated="True" extra-ref="ConfidentialVirtualization"/>
|
||||
+
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Architecture"/>
|
||||
|
||||
<variablelist class="dbus-property" generated="True" extra-ref="Tainted"/>
|
||||
@@ -1695,6 +1699,12 @@ node /org/freedesktop/systemd1 {
|
||||
Note that only the "innermost" virtualization technology is exported here. This detects both
|
||||
full-machine virtualizations (VMs) and shared-kernel virtualization (containers).</para>
|
||||
|
||||
+ <para><varname>ConfidentialVirtualization</varname> contains a short ID string describing the confidential
|
||||
+ virtualization technology the system runs in. On bare-metal hardware this is the empty string. Otherwise,
|
||||
+ it contains an identifier such as <literal>sev</literal>, <literal>sev-es</literal>, <literal>sev-snp</literal>,
|
||||
+ <literal>tdx</literal> and so on. For a full list of IDs see
|
||||
+ <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry></para>.
|
||||
+
|
||||
<para><varname>Architecture</varname> contains a short ID string describing the architecture the
|
||||
systemd instance is running on. This follows the same vocabulary as
|
||||
<varname>ConditionArchitectures=</varname>.</para>
|
||||
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
|
||||
index 44b1027588..386b319c86 100644
|
||||
--- a/src/core/dbus-manager.c
|
||||
+++ b/src/core/dbus-manager.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "bus-get-properties.h"
|
||||
#include "bus-log-control-api.h"
|
||||
#include "chase-symlinks.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "data-fd-util.h"
|
||||
#include "dbus-cgroup.h"
|
||||
#include "dbus-execute.h"
|
||||
@@ -91,6 +92,27 @@ static int property_get_virtualization(
|
||||
v == VIRTUALIZATION_NONE ? NULL : virtualization_to_string(v));
|
||||
}
|
||||
|
||||
+static int property_get_confidential_virtualization(
|
||||
+ sd_bus *bus,
|
||||
+ const char *path,
|
||||
+ const char *interface,
|
||||
+ const char *property,
|
||||
+ sd_bus_message *reply,
|
||||
+ void *userdata,
|
||||
+ sd_bus_error *error) {
|
||||
+
|
||||
+ ConfidentialVirtualization v;
|
||||
+
|
||||
+ assert(bus);
|
||||
+ assert(reply);
|
||||
+
|
||||
+ v = detect_confidential_virtualization();
|
||||
+
|
||||
+ return sd_bus_message_append(
|
||||
+ reply, "s",
|
||||
+ v <= 0 ? NULL : confidential_virtualization_to_string(v));
|
||||
+}
|
||||
+
|
||||
static int property_get_tainted(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@@ -2785,6 +2807,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
+ SD_BUS_PROPERTY("ConfidentialVirtualization", "s", property_get_confidential_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
@ -0,0 +1,40 @@
|
||||
From 8e90076fa7503595ebf413ebeb9dff46907e9967 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 3 Jul 2023 10:20:47 +0100
|
||||
Subject: [PATCH] core: log detected confidential virtualization type
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 024469ddb99ebbf0e0b0f1d77f763116ca251c5d)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
src/core/main.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/src/core/main.c b/src/core/main.c
|
||||
index e7b8e98bca..f230270340 100644
|
||||
--- a/src/core/main.c
|
||||
+++ b/src/core/main.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "cgroup-util.h"
|
||||
#include "clock-util.h"
|
||||
#include "conf-parser.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "crash-handler.h"
|
||||
#include "dbus-manager.h"
|
||||
@@ -2060,6 +2061,10 @@ static void log_execution_mode(bool *ret_first_boot) {
|
||||
if (v > 0)
|
||||
log_info("Detected virtualization %s.", virtualization_to_string(v));
|
||||
|
||||
+ v = detect_confidential_virtualization();
|
||||
+ if (v > 0)
|
||||
+ log_info("Detected confidential virtualization %s.", confidential_virtualization_to_string(v));
|
||||
+
|
||||
log_info("Detected architecture %s.", architecture_to_string(uname_architecture()));
|
||||
|
||||
if (in_initrd())
|
@ -0,0 +1,80 @@
|
||||
From 727b779b866e11834d1d0414d677b29702cadbfa Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 3 Jul 2023 10:21:07 +0100
|
||||
Subject: [PATCH] core: set SYSTEMD_CONFIDENTIAL_VIRTUALIZATION env for
|
||||
generators
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This reports the confidential virtualization type that was detected
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 0895124572c5a035d45f08cfbcdc0cdd61cead4c)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/systemd.generator.xml | 12 ++++++++++++
|
||||
src/core/manager.c | 11 +++++++++++
|
||||
2 files changed, 23 insertions(+)
|
||||
|
||||
diff --git a/man/systemd.generator.xml b/man/systemd.generator.xml
|
||||
index 19ec586fa0..b3f19296f9 100644
|
||||
--- a/man/systemd.generator.xml
|
||||
+++ b/man/systemd.generator.xml
|
||||
@@ -185,6 +185,18 @@
|
||||
<varname>ConditionArchitecture=</varname> in
|
||||
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
||||
</varlistentry>
|
||||
+
|
||||
+ <varlistentry>
|
||||
+ <term><varname>$SYSTEMD_CONFIDENTIAL_VIRTUALIZATION</varname></term>
|
||||
+
|
||||
+ <listitem><para>If the service manager is run in a confidential virtualized environment,
|
||||
+ <varname>$SYSTEMD_CONFIDENTIAL_VIRTUALIZATION</varname> is set to a string that identifies
|
||||
+ the confidential virtualization hardware technology. If no confidential virtualization is
|
||||
+ detected this variable will not be set. This data is identical to what
|
||||
+ <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
+ detects and reports, and uses the same vocabulary of confidential virtualization
|
||||
+ technology identifiers.</para></listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index b44c7785cf..daeaa641d7 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "bus-util.h"
|
||||
#include "clean-ipc.h"
|
||||
#include "clock-util.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "core-varlink.h"
|
||||
#include "creds-util.h"
|
||||
#include "dbus-job.h"
|
||||
@@ -3706,6 +3707,7 @@ static int manager_run_environment_generators(Manager *m) {
|
||||
static int build_generator_environment(Manager *m, char ***ret) {
|
||||
_cleanup_strv_free_ char **nl = NULL;
|
||||
Virtualization v;
|
||||
+ ConfidentialVirtualization cv;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -3754,6 +3756,15 @@ static int build_generator_environment(Manager *m, char ***ret) {
|
||||
return r;
|
||||
}
|
||||
|
||||
+ cv = detect_confidential_virtualization();
|
||||
+ if (cv < 0)
|
||||
+ log_debug_errno(cv, "Failed to detect confidential virtualization, ignoring: %m");
|
||||
+ else if (cv > 0) {
|
||||
+ r = strv_env_assign(&nl, "SYSTEMD_CONFIDENTIAL_VIRTUALIZATION", confidential_virtualization_to_string(cv));
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+ }
|
||||
+
|
||||
r = strv_env_assign(&nl, "SYSTEMD_ARCHITECTURE", architecture_to_string(uname_architecture()));
|
||||
if (r < 0)
|
||||
return r;
|
@ -0,0 +1,59 @@
|
||||
From 586b33b02ddc3375181fc37a14b7eb94d3eba796 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Mon, 3 Jul 2023 10:24:30 +0100
|
||||
Subject: [PATCH] udev: add 'conf-virt' constant for confidential
|
||||
virtualization tech
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Related: https://github.com/systemd/systemd/issues/27604
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 6e2e83b48734e86992cbbdb329c48cc066cf7c96)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/udev.xml | 8 ++++++++
|
||||
src/udev/udev-rules.c | 3 +++
|
||||
2 files changed, 11 insertions(+)
|
||||
|
||||
diff --git a/man/udev.xml b/man/udev.xml
|
||||
index 5b096c7ef2..a96400e29d 100644
|
||||
--- a/man/udev.xml
|
||||
+++ b/man/udev.xml
|
||||
@@ -279,6 +279,14 @@
|
||||
for possible values.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
+ <varlistentry>
|
||||
+ <term><literal>cvm</literal></term>
|
||||
+ <listitem>
|
||||
+ <para>System's confidential virtualization technology. See
|
||||
+ <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
+ for possible values.</para>
|
||||
+ </listitem>
|
||||
+ </varlistentry>
|
||||
</variablelist>
|
||||
<para>Unknown keys will never match.</para>
|
||||
</listitem>
|
||||
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
|
||||
index 9336ce1cd3..3fcbf818d7 100644
|
||||
--- a/src/udev/udev-rules.c
|
||||
+++ b/src/udev/udev-rules.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "architecture.h"
|
||||
#include "conf-files.h"
|
||||
#include "conf-parser.h"
|
||||
+#include "confidential-virt.h"
|
||||
#include "def.h"
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
@@ -1681,6 +1682,8 @@ static int udev_rule_apply_token_to_event(
|
||||
val = architecture_to_string(uname_architecture());
|
||||
else if (streq(k, "virt"))
|
||||
val = virtualization_to_string(detect_virtualization());
|
||||
+ else if (streq(k, "cvm"))
|
||||
+ val = confidential_virtualization_to_string(detect_confidential_virtualization());
|
||||
else
|
||||
assert_not_reached();
|
||||
return token_match_string(token, val);
|
@ -0,0 +1,76 @@
|
||||
From 59055cd4f4ce89150dfe6bdadf3a3ced78009b15 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 2 Aug 2024 16:26:00 +0100
|
||||
Subject: [PATCH] confidential-virt: split caching of CVM detection into
|
||||
separate method
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
We have different impls of detect_confidential_virtualization per
|
||||
architecture. The detection is cached in the x86_64 impl, and as we
|
||||
add support for more targets, we want to use caching for all. It thus
|
||||
makes sense to split caching out into an architecture independent
|
||||
method.
|
||||
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 1c4bd7adcc281af2a2dd40867f64f2ac54a43c7a)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
src/basic/confidential-virt.c | 25 ++++++++++++++-----------
|
||||
1 file changed, 14 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c
|
||||
index 3d4e9eac33..5c96b449b1 100644
|
||||
--- a/src/basic/confidential-virt.c
|
||||
+++ b/src/basic/confidential-virt.c
|
||||
@@ -254,34 +254,37 @@ static bool detect_hypervisor(void) {
|
||||
return is_hv;
|
||||
}
|
||||
|
||||
-ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
- static thread_local ConfidentialVirtualization cached_found = _CONFIDENTIAL_VIRTUALIZATION_INVALID;
|
||||
+static ConfidentialVirtualization detect_confidential_virtualization_impl(void) {
|
||||
char sig[13] = {};
|
||||
- ConfidentialVirtualization cv = CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
-
|
||||
- if (cached_found >= 0)
|
||||
- return cached_found;
|
||||
|
||||
/* Skip everything on bare metal */
|
||||
if (detect_hypervisor()) {
|
||||
cpuid_leaf(0, sig, true);
|
||||
|
||||
if (memcmp(sig, CPUID_SIG_AMD, sizeof(sig)) == 0)
|
||||
- cv = detect_sev();
|
||||
+ return detect_sev();
|
||||
else if (memcmp(sig, CPUID_SIG_INTEL, sizeof(sig)) == 0)
|
||||
- cv = detect_tdx();
|
||||
+ return detect_tdx();
|
||||
}
|
||||
|
||||
- cached_found = cv;
|
||||
- return cv;
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
}
|
||||
#else /* ! x86_64 */
|
||||
-ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
+static ConfidentialVirtualization detect_confidential_virtualization_impl(void) {
|
||||
log_debug("No confidential virtualization detection on this architecture");
|
||||
return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
}
|
||||
#endif /* ! x86_64 */
|
||||
|
||||
+ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
+ static thread_local ConfidentialVirtualization cached_found = _CONFIDENTIAL_VIRTUALIZATION_INVALID;
|
||||
+
|
||||
+ if (cached_found == _CONFIDENTIAL_VIRTUALIZATION_INVALID)
|
||||
+ cached_found = detect_confidential_virtualization_impl();
|
||||
+
|
||||
+ return cached_found;
|
||||
+}
|
||||
+
|
||||
static const char *const confidential_virtualization_table[_CONFIDENTIAL_VIRTUALIZATION_MAX] = {
|
||||
[CONFIDENTIAL_VIRTUALIZATION_NONE] = "none",
|
||||
[CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev",
|
90
1035-confidential-virt-add-detection-for-s390x-target.patch
Normal file
90
1035-confidential-virt-add-detection-for-s390x-target.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From f47239f3e5aed9d7887aac1b15021f5c63996378 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 2 Aug 2024 11:03:10 +0100
|
||||
Subject: [PATCH] confidential-virt: add detection for s390x target
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The s390x platform provides confidential VMs using the "Secure Execution"
|
||||
technology, which is also referred to as "Protected Virtualization" or
|
||||
just "prot virt" in Linux / QEMU.
|
||||
|
||||
This can be detected through a simple sysfs attribute.
|
||||
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit 6c35e0a51cc6a852ce239ea46cd75c133212a68e)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
src/basic/confidential-virt.c | 30 +++++++++++++++++++++++++-----
|
||||
src/basic/confidential-virt.h | 1 +
|
||||
2 files changed, 26 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/src/basic/confidential-virt.c b/src/basic/confidential-virt.c
|
||||
index 5c96b449b1..746aa8c313 100644
|
||||
--- a/src/basic/confidential-virt.c
|
||||
+++ b/src/basic/confidential-virt.c
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "confidential-virt.h"
|
||||
#include "fd-util.h"
|
||||
+#include "fileio.h"
|
||||
#include "missing_threads.h"
|
||||
#include "string-table.h"
|
||||
#include "utf8.h"
|
||||
@@ -269,6 +270,24 @@ static ConfidentialVirtualization detect_confidential_virtualization_impl(void)
|
||||
|
||||
return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
}
|
||||
+#elif defined(__s390x__)
|
||||
+static ConfidentialVirtualization detect_confidential_virtualization_impl(void) {
|
||||
+ _cleanup_free_ char *s = NULL;
|
||||
+ size_t readsize;
|
||||
+ int r;
|
||||
+
|
||||
+ r = read_full_virtual_file("/sys/firmware/uv/prot_virt_guest", &s, &readsize);
|
||||
+ if (r < 0) {
|
||||
+ log_debug_errno(r, "Unable to read /sys/firmware/uv/prot_virt_guest: %m");
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+ }
|
||||
+
|
||||
+ if (readsize >= 1 && s[0] == '1')
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_PROTVIRT;
|
||||
+
|
||||
+ return CONFIDENTIAL_VIRTUALIZATION_NONE;
|
||||
+}
|
||||
+
|
||||
#else /* ! x86_64 */
|
||||
static ConfidentialVirtualization detect_confidential_virtualization_impl(void) {
|
||||
log_debug("No confidential virtualization detection on this architecture");
|
||||
@@ -286,11 +305,12 @@ ConfidentialVirtualization detect_confidential_virtualization(void) {
|
||||
}
|
||||
|
||||
static const char *const confidential_virtualization_table[_CONFIDENTIAL_VIRTUALIZATION_MAX] = {
|
||||
- [CONFIDENTIAL_VIRTUALIZATION_NONE] = "none",
|
||||
- [CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev",
|
||||
- [CONFIDENTIAL_VIRTUALIZATION_SEV_ES] = "sev-es",
|
||||
- [CONFIDENTIAL_VIRTUALIZATION_SEV_SNP] = "sev-snp",
|
||||
- [CONFIDENTIAL_VIRTUALIZATION_TDX] = "tdx",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_NONE] = "none",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV] = "sev",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV_ES] = "sev-es",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_SEV_SNP] = "sev-snp",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_TDX] = "tdx",
|
||||
+ [CONFIDENTIAL_VIRTUALIZATION_PROTVIRT] = "protvirt",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(confidential_virtualization, ConfidentialVirtualization);
|
||||
diff --git a/src/basic/confidential-virt.h b/src/basic/confidential-virt.h
|
||||
index c02f3b2321..f92e3e883d 100644
|
||||
--- a/src/basic/confidential-virt.h
|
||||
+++ b/src/basic/confidential-virt.h
|
||||
@@ -13,6 +13,7 @@ typedef enum ConfidentialVirtualization {
|
||||
CONFIDENTIAL_VIRTUALIZATION_SEV_ES,
|
||||
CONFIDENTIAL_VIRTUALIZATION_SEV_SNP,
|
||||
CONFIDENTIAL_VIRTUALIZATION_TDX,
|
||||
+ CONFIDENTIAL_VIRTUALIZATION_PROTVIRT,
|
||||
|
||||
_CONFIDENTIAL_VIRTUALIZATION_MAX,
|
||||
_CONFIDENTIAL_VIRTUALIZATION_INVALID = -EINVAL,
|
@ -0,0 +1,74 @@
|
||||
From 11992ca0dbeb077dbf4c033fe8a19a1ef19d7e57 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
||||
Date: Fri, 2 Aug 2024 13:17:56 +0100
|
||||
Subject: [PATCH] man/systemd-detect-virt: list known CVM technologies
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Add a section which lists the known confidential virtual machine
|
||||
technologies.
|
||||
|
||||
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
||||
(cherry picked from commit a8fb5d21fd6127a6d05757c793cc9ba47f65c893)
|
||||
|
||||
Related: RHEL-50651
|
||||
---
|
||||
man/systemd-detect-virt.xml | 44 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 44 insertions(+)
|
||||
|
||||
diff --git a/man/systemd-detect-virt.xml b/man/systemd-detect-virt.xml
|
||||
index 5aaff839a4..428c5a86fa 100644
|
||||
--- a/man/systemd-detect-virt.xml
|
||||
+++ b/man/systemd-detect-virt.xml
|
||||
@@ -207,6 +207,50 @@
|
||||
WSL is categorized as a container for practical purposes.
|
||||
Multiple WSL environments share the same kernel and services
|
||||
should generally behave like when being run in a container.</para>
|
||||
+
|
||||
+ <para>When executed with <option>--cvm</option>, instead of
|
||||
+ printing the virtualization technology, it will display the
|
||||
+ confidential virtual machine technology, if any. The
|
||||
+ following technologies are currently identified:</para>
|
||||
+
|
||||
+ <table>
|
||||
+ <title>Known confidential virtualization technologies</title>
|
||||
+ <tgroup cols='2' align='left' colsep='1' rowsep='1'>
|
||||
+ <colspec colname="id" />
|
||||
+ <colspec colname="product" />
|
||||
+ <thead>
|
||||
+ <row>
|
||||
+ <entry>Arch</entry>
|
||||
+ <entry>ID</entry>
|
||||
+ <entry>Technology</entry>
|
||||
+ </row>
|
||||
+ </thead>
|
||||
+ <tbody>
|
||||
+ <row>
|
||||
+ <entry valign="top" morerows="3">x86_64</entry>
|
||||
+ <entry><varname>sev</varname></entry>
|
||||
+ <entry>AMD Secure Encrypted Virtualization</entry>
|
||||
+ </row>
|
||||
+ <row>
|
||||
+ <entry><varname>sev-es</varname></entry>
|
||||
+ <entry>AMD Secure Encrypted Virtualization - Encrypted State</entry>
|
||||
+ </row>
|
||||
+ <row>
|
||||
+ <entry><varname>sev-snp</varname></entry>
|
||||
+ <entry>AMD Secure Encrypted Virtualization - Secure Nested Paging</entry>
|
||||
+ </row>
|
||||
+ <row>
|
||||
+ <entry><varname>tdx</varname></entry>
|
||||
+ <entry>Intel Trust Domain Extensions</entry>
|
||||
+ </row>
|
||||
+ <row>
|
||||
+ <entry>s390x</entry>
|
||||
+ <entry><varname>protvirt</varname></entry>
|
||||
+ <entry>IBM Protected Virtualization (Secure Execution)</entry>
|
||||
+ </row>
|
||||
+ </tbody>
|
||||
+ </tgroup>
|
||||
+ </table>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
36
systemd.spec
36
systemd.spec
@ -25,7 +25,7 @@
|
||||
Name: systemd
|
||||
Url: https://systemd.io
|
||||
Version: 252
|
||||
Release: 42%{?dist}
|
||||
Release: 43%{?dist}
|
||||
# For a breakdown of the licensing, see README
|
||||
License: LGPLv2+ and MIT and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
@ -1109,6 +1109,22 @@ Patch1017: 1017-add-udev-rules-for-trezor-hw-wallet-devices.patch
|
||||
Patch1018: 1018-hwdb-add-axis-range-corrections-for-the-Lenovo-Think.patch
|
||||
Patch1019: 1019-hwdb-fix-auto-rotate-on-Asus-Q551LB-33921.patch
|
||||
Patch1020: 1020-udev-add-hwdb-execution-for-hidraw-subsystem-devices.patch
|
||||
Patch1021: 1021-udev-builtin-net_id-skip-non-directory-entry-earlier.patch
|
||||
Patch1022: 1022-udev-builtin-net_id-return-earlier-when-hotplug-slot.patch
|
||||
Patch1023: 1023-udev-builtin-net_id-split-out-pci_get_hotplug_slot-a.patch
|
||||
Patch1024: 1024-udev-builtin-net_id-use-firmware_node-sun-for-ID_NET.patch
|
||||
Patch1025: 1025-Include-threads.h-if-possible-to-get-thread_local-de.patch
|
||||
Patch1026: 1026-add-APIs-for-detecting-confidential-virtualization.patch
|
||||
Patch1027: 1027-detect-virt-add-cvm-option.patch
|
||||
Patch1028: 1028-detect-virt-add-list-cvm-option.patch
|
||||
Patch1029: 1029-unit-add-cvm-option-for-ConditionSecurity.patch
|
||||
Patch1030: 1030-dbus-add-ConfidentialVirtualization-property-to-mana.patch
|
||||
Patch1031: 1031-core-log-detected-confidential-virtualization-type.patch
|
||||
Patch1032: 1032-core-set-SYSTEMD_CONFIDENTIAL_VIRTUALIZATION-env-for.patch
|
||||
Patch1033: 1033-udev-add-conf-virt-constant-for-confidential-virtual.patch
|
||||
Patch1034: 1034-confidential-virt-split-caching-of-CVM-detection-int.patch
|
||||
Patch1035: 1035-confidential-virt-add-detection-for-s390x-target.patch
|
||||
Patch1036: 1036-man-systemd-detect-virt-list-known-CVM-technologies.patch
|
||||
|
||||
# Downstream-only patches (9000–9999)
|
||||
|
||||
@ -1991,6 +2007,24 @@ systemd-hwdb update &>/dev/null || :
|
||||
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
|
||||
|
||||
%changelog
|
||||
* Thu Aug 22 2024 systemd maintenance team <systemd-maint@redhat.com> - 252-43
|
||||
- udev-builtin-net_id: skip non-directory entry earlier (RHEL-50103)
|
||||
- udev-builtin-net_id: return earlier when hotplug slot is not found (RHEL-50103)
|
||||
- udev-builtin-net_id: split-out pci_get_hotplug_slot() and pci_get_hotplug_slot_from_address() (RHEL-50103)
|
||||
- udev-builtin-net_id: use firmware_node/sun for ID_NET_NAME_SLOT (RHEL-50103)
|
||||
- Include <threads.h> if possible to get thread_local definition (RHEL-50651)
|
||||
- add APIs for detecting confidential virtualization (RHEL-50651)
|
||||
- detect-virt: add --cvm option (RHEL-50651)
|
||||
- detect-virt: add --list-cvm option (RHEL-50651)
|
||||
- unit: add "cvm" option for ConditionSecurity (RHEL-50651)
|
||||
- dbus: add 'ConfidentialVirtualization' property to manager object (RHEL-50651)
|
||||
- core: log detected confidential virtualization type (RHEL-50651)
|
||||
- core: set SYSTEMD_CONFIDENTIAL_VIRTUALIZATION env for generators (RHEL-50651)
|
||||
- udev: add 'conf-virt' constant for confidential virtualization tech (RHEL-50651)
|
||||
- confidential-virt: split caching of CVM detection into separate method (RHEL-50651)
|
||||
- confidential-virt: add detection for s390x target (RHEL-50651)
|
||||
- man/systemd-detect-virt: list known CVM technologies (RHEL-50651)
|
||||
|
||||
* Mon Aug 19 2024 systemd team <systemd-maint@redhat.com>
|
||||
- fix applying patches
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user