-
-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a patch for conditional IOMMU-less passthrough on PV domain
Look for qubes.enable_insecure_pv_passthrough on dom0 kernel cmdline. If it's present, allow creating PV domain with PCI devices even if IOMMU is not present/enabled. QubesOS/qubes-issues#5529
- Loading branch information
Showing
2 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
124 changes: 124 additions & 0 deletions
124
patch-0001-libxl-conditionally-allow-PCI-passthrough-on-PV-with.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
From b6e6aaae8b9547b3afe8a9254fbf8f2008b75d6f Mon Sep 17 00:00:00 2001 | ||
From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= | ||
<marmarek@invisiblethingslab.com> | ||
Date: Sat, 16 Jan 2021 05:06:18 +0100 | ||
Subject: [PATCH] libxl: conditionally allow PCI passthrough on PV without | ||
IOMMU | ||
MIME-Version: 1.0 | ||
Content-Type: text/plain; charset=UTF-8 | ||
Content-Transfer-Encoding: 8bit | ||
Organization: Invisible Things Lab | ||
Cc: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> | ||
|
||
Without IOMMU, PCI passthrough cannot be used securely. But there are | ||
still various Qubes OS features that would be useful and improve overall | ||
system trustworthiness compared to monolithic system. | ||
This is also handy for development, to allow running Qubes OS nested | ||
withing KVM (on AMD, vIOMMU is unstable). | ||
|
||
Signed-off-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com> | ||
--- | ||
tools/libxl/libxl_create.c | 8 ++++++- | ||
tools/libxl/libxl_internal.h | 2 ++ | ||
tools/libxl/libxl_pci.c | 41 ++++++++++++++++++++++++++++++++++-- | ||
3 files changed, 48 insertions(+), 3 deletions(-) | ||
|
||
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c | ||
index 2814818e34d2..90aa0a35cdc8 100644 | ||
--- a/tools/libxl/libxl_create.c | ||
+++ b/tools/libxl/libxl_create.c | ||
@@ -1097,12 +1097,18 @@ int libxl__domain_config_setdefault(libxl__gc *gc, | ||
} | ||
|
||
bool need_pt = d_config->num_pcidevs || d_config->num_dtdevs; | ||
+ bool iommu_enabled = physinfo.cap_hvm_directio; | ||
+ if (need_pt && !iommu_enabled && | ||
+ c_info->type == LIBXL_DOMAIN_TYPE_PV && | ||
+ libxl__is_insecure_pv_passthrough_enabled(gc)) { | ||
+ /* allow insecure PV with IOMMU usage */ | ||
+ need_pt = false; | ||
+ } | ||
if (c_info->passthrough == LIBXL_PASSTHROUGH_DEFAULT) { | ||
c_info->passthrough = need_pt | ||
? LIBXL_PASSTHROUGH_ENABLED : LIBXL_PASSTHROUGH_DISABLED; | ||
} | ||
|
||
- bool iommu_enabled = physinfo.cap_hvm_directio; | ||
if (c_info->passthrough != LIBXL_PASSTHROUGH_DISABLED && !iommu_enabled) { | ||
LOGD(ERROR, domid, | ||
"passthrough not supported on this platform\n"); | ||
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h | ||
index 94a23179d30a..a5b3bbcdf094 100644 | ||
--- a/tools/libxl/libxl_internal.h | ||
+++ b/tools/libxl/libxl_internal.h | ||
@@ -4819,6 +4819,8 @@ static inline const char *libxl__qemu_qmp_path(libxl__gc *gc, int domid) | ||
return GCSPRINTF("%s/qmp-libxl-%d", libxl__run_dir_path(), domid); | ||
} | ||
|
||
+_hidden bool libxl__is_insecure_pv_passthrough_enabled(libxl__gc *gc); | ||
+ | ||
/* Send control commands over xenstore and wait for an Ack. */ | ||
_hidden int libxl__domain_pvcontrol(libxl__egc *egc, | ||
libxl__xswait_state *pvcontrol, | ||
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c | ||
index bc5843b13701..ea476e5e4ca1 100644 | ||
--- a/tools/libxl/libxl_pci.c | ||
+++ b/tools/libxl/libxl_pci.c | ||
@@ -1432,8 +1432,10 @@ out_no_irq: | ||
r = xc_assign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev), flag); | ||
if (r < 0 && (hvm || errno != ENOSYS)) { | ||
LOGED(ERROR, domainid, "xc_assign_device failed"); | ||
- rc = ERROR_FAIL; | ||
- goto out; | ||
+ if (hvm || errno != EOPNOTSUPP || libxl__is_insecure_pv_passthrough_enabled(gc)) { | ||
+ rc = ERROR_FAIL; | ||
+ goto out; | ||
+ } | ||
} | ||
} | ||
|
||
@@ -2486,6 +2488,41 @@ int libxl__grant_vga_iomem_permission(libxl__gc *gc, const uint32_t domid, | ||
return 0; | ||
} | ||
|
||
+bool libxl__is_insecure_pv_passthrough_enabled(libxl__gc *gc) | ||
+{ | ||
+ FILE *f = fopen("/proc/cmdline", "r"); | ||
+ char cmdline[4096], *tok; | ||
+ size_t read_s; | ||
+ static int is_enabled = -1; | ||
+ | ||
+ if (is_enabled != -1) | ||
+ return is_enabled; | ||
+ | ||
+ if (!f) { | ||
+ LOG(WARN, "Failed to open /proc/cmdline: %d", errno); | ||
+ return false; | ||
+ } | ||
+ read_s = fread(cmdline, 1, sizeof(cmdline) - 1, f); | ||
+ if (!feof(f) || ferror(f)) { | ||
+ LOG(WARN, "Failed to read /proc/cmdline: %d", errno); | ||
+ fclose(f); | ||
+ return false; | ||
+ } | ||
+ cmdline[read_s] = 0; | ||
+ fclose(f); | ||
+ | ||
+ tok = strtok(cmdline, " \n"); | ||
+ while (tok) { | ||
+ if (strcmp(tok, "qubes.enable_insecure_pv_passthrough") == 0) { | ||
+ is_enabled = 1; | ||
+ return true; | ||
+ } | ||
+ tok = strtok(NULL, " \n"); | ||
+ } | ||
+ is_enabled = 0; | ||
+ return false; | ||
+} | ||
+ | ||
static int libxl_device_pci_compare(const libxl_device_pci *d1, | ||
const libxl_device_pci *d2) | ||
{ | ||
-- | ||
2.25.4 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters