kmod-setup: support early loading for virtio-ccw devices
Before this change, the code checked for presence of virtio-pci devices to decide whether transport-agnostic virtio drivers needed to be loaded early. Do it also if virtio-ccw devices are present, that is, devices with the control unit type (CU type) 0x3832, under /sys/devices/css0. (This CU type value is documented in "Virtio Over Channel I/O" virtio specification section.) In other words, extend to virtio-ccw devices the fix previously done for virtio-pci: #40161: commit356cc4a1c3#40503: commit6d36e5fae6Tested-by: Marc Hartmayer <marc@linux.ibm.com> Reviewed-by: Marc Hartmayer <marc@linux.ibm.com>
This commit is contained in:
committed by
Yu Watanabe
parent
d56d8d43ee
commit
d1697c4ff8
+84
-8
@@ -15,7 +15,7 @@
|
||||
#include "virt.h"
|
||||
|
||||
#if HAVE_KMOD
|
||||
static int match_modalias_recurse_dir_cb(
|
||||
static int match_pci_modalias_recurse_dir_cb(
|
||||
RecurseDirEvent event,
|
||||
const char *path,
|
||||
int dir_fd,
|
||||
@@ -49,7 +49,7 @@ static int match_modalias_recurse_dir_cb(
|
||||
return RECURSE_DIR_LEAVE_DIRECTORY;
|
||||
}
|
||||
|
||||
static bool has_virtio_feature(const char *name, char **modaliases) {
|
||||
static bool has_virtio_pci_feature(const char *name, char **modaliases) {
|
||||
int r;
|
||||
|
||||
/* Directory traversal might be slow, hence let's do a cheap check first if it's even worth it */
|
||||
@@ -62,25 +62,100 @@ static bool has_virtio_feature(const char *name, char **modaliases) {
|
||||
/* statx_mask= */ 0,
|
||||
/* n_depth_max= */ 3,
|
||||
RECURSE_DIR_ENSURE_TYPE,
|
||||
match_modalias_recurse_dir_cb,
|
||||
match_pci_modalias_recurse_dir_cb,
|
||||
modaliases);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to determine whether host has %s device, ignoring: %m", name);
|
||||
log_debug_errno(r, "Failed to determine whether host has %s PCI device, ignoring: %m", name);
|
||||
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
#if defined(__s390__) || defined(__s390x__)
|
||||
static int match_ccw_modalias_recurse_dir_cb(
|
||||
RecurseDirEvent event,
|
||||
const char *path,
|
||||
int dir_fd,
|
||||
int inode_fd,
|
||||
const struct dirent *de,
|
||||
const struct statx *sx,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_free_ char *alias = NULL;
|
||||
char **modaliases = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
if (event != RECURSE_DIR_ENTRY)
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
if (de->d_type != DT_REG)
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
if (!streq(de->d_name, "modalias"))
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
|
||||
/* Unlike PCI's "recurse_dir_cb", upon finding a non-matching modalias,
|
||||
* we don't abandon the current directory but keep looking for virtio
|
||||
* devices in subdirectories, by returning RECURSE_DIR_CONTINUE. */
|
||||
r = read_one_line_file(path, &alias);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to read %s, ignoring: %m", path);
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
}
|
||||
|
||||
if (startswith_strv(alias, modaliases))
|
||||
return 1;
|
||||
|
||||
return RECURSE_DIR_CONTINUE;
|
||||
}
|
||||
|
||||
static bool has_virtio_ccw_feature(const char *name, char **modaliases) {
|
||||
int r;
|
||||
|
||||
/* Directory traversal might be slow, hence let's do a cheap check first if it's even worth it */
|
||||
if (detect_vm() == VIRTUALIZATION_NONE)
|
||||
return false;
|
||||
|
||||
r = recurse_dir_at(
|
||||
AT_FDCWD,
|
||||
"/sys/devices/css0",
|
||||
/* statx_mask= */ 0,
|
||||
/* n_depth_max= */ 3,
|
||||
RECURSE_DIR_ENSURE_TYPE,
|
||||
match_ccw_modalias_recurse_dir_cb,
|
||||
modaliases);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to determine whether host has %s CCW device, ignoring: %m", name);
|
||||
|
||||
return r > 0;
|
||||
}
|
||||
|
||||
static bool has_virtio_ccw(void) {
|
||||
/* All virtio-ccw devices use the control unit type (CU type) 0x3832 */
|
||||
return has_virtio_ccw_feature("virtio-ccw", STRV_MAKE("ccw:t3832"));
|
||||
}
|
||||
#else
|
||||
static bool has_virtio_ccw_feature(const char *name, char **modaliases) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool has_virtio_ccw(void) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool has_virtio_rng(void) {
|
||||
return has_virtio_feature("virtio-rng", STRV_MAKE("pci:v00001AF4d00001005", "pci:v00001AF4d00001044"));
|
||||
return has_virtio_pci_feature("virtio-rng", STRV_MAKE("pci:v00001AF4d00001005", "pci:v00001AF4d00001044")) ||
|
||||
has_virtio_ccw_feature("virtio-rng", STRV_MAKE("ccw:t3832m04"));
|
||||
}
|
||||
|
||||
static bool has_virtio_pci(void) {
|
||||
return has_virtio_feature("virtio-pci", STRV_MAKE("pci:v00001AF4d"));
|
||||
return has_virtio_pci_feature("virtio-pci", STRV_MAKE("pci:v00001AF4d"));
|
||||
}
|
||||
|
||||
static bool may_have_virtio(void) {
|
||||
/* FIXME: strictly speaking, other virtio features, e.g. vsock, are independent of the virtio PCI device. */
|
||||
return has_virtio_pci();
|
||||
/* FIXME: strictly speaking, other virtio features, e.g. vsock, are independent of the virtio PCI
|
||||
* or CCW device. */
|
||||
return has_virtio_pci() || has_virtio_ccw();
|
||||
}
|
||||
|
||||
static bool in_qemu(void) {
|
||||
@@ -139,6 +214,7 @@ int kmod_setup(void) {
|
||||
* resolved and the kernel fix is widely available. */
|
||||
{ "virtiofs", "/sys/module/virtiofs", false, false, may_have_virtio },
|
||||
{ "virtio_pci", "/sys/module/virtio_pci", false, false, has_virtio_pci },
|
||||
{ "virtio_ccw", "/sys/module/virtio_ccw", false, false, has_virtio_ccw },
|
||||
|
||||
/* qemu_fw_cfg would be loaded by udev later, but we want to import credentials from it super early */
|
||||
{ "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu },
|
||||
|
||||
Reference in New Issue
Block a user