|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH V2 9/25] tools/libxl: build DMAR table for a guest with one virtual VTD
From: Chao Gao <chao.gao@xxxxxxxxx>
A new logic is added to build ACPI DMAR table in tool stack for a guest
with one virtual VTD and pass through it to guest via existing mechanism. If
there already are ACPI tables needed to pass through, we joint the tables.
Signed-off-by: Chao Gao <chao.gao@xxxxxxxxx>
Signed-off-by: Lan Tianyu <tianyu.lan@xxxxxxxxx>
---
tools/libxl/libxl_arch.h | 5 +++++
tools/libxl/libxl_dom.c | 36 +++++++++++++++++++++++++++++++++
tools/libxl/libxl_x86_acpi.c | 48 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 89 insertions(+)
diff --git a/tools/libxl/libxl_arch.h b/tools/libxl/libxl_arch.h
index 5e1fc60..d8ddd60 100644
--- a/tools/libxl/libxl_arch.h
+++ b/tools/libxl/libxl_arch.h
@@ -78,6 +78,11 @@ int libxl__arch_extra_memory(libxl__gc *gc,
int libxl__dom_load_acpi(libxl__gc *gc,
const libxl_domain_build_info *b_info,
struct xc_dom_image *dom);
+
+int libxl__dom_build_dmar(libxl__gc *gc,
+ const libxl_domain_build_info *b_info,
+ struct xc_dom_image *dom,
+ void **data, int *len);
#endif
#endif
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index f54fd49..94c9196 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1060,6 +1060,42 @@ static int libxl__domain_firmware(libxl__gc *gc,
}
}
+ /*
+ * If a guest has one virtual VTD, build DMAR table for it and joint this
+ * table with existing content in acpi_modules in order to employ HVM
+ * firmware pass-through mechanism to pass-through DMAR table.
+ */
+ if (info->viommu.type == LIBXL_VIOMMU_TYPE_INTEL_VTD) {
+ datalen = 0;
+ e = libxl__dom_build_dmar(gc, info, dom, &data, &datalen);
+ if (e) {
+ LOGEV(ERROR, e, "failed to build DMAR table");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ if (datalen) {
+ libxl__ptr_add(gc, data);
+ if (!dom->acpi_modules[0].data) {
+ dom->acpi_modules[0].data = data;
+ dom->acpi_modules[0].length = (uint32_t)datalen;
+ } else {
+ /* joint tables */
+ void *newdata;
+ newdata = malloc(datalen + dom->acpi_modules[0].length);
+ if (!newdata) {
+ LOGE(ERROR, "failed to joint DMAR table to acpi modules");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ memcpy(newdata, dom->acpi_modules[0].data,
+ dom->acpi_modules[0].length);
+ memcpy(newdata + dom->acpi_modules[0].length, data, datalen);
+ dom->acpi_modules[0].data = newdata;
+ dom->acpi_modules[0].length += (uint32_t)datalen;
+ }
+ }
+ }
+
return 0;
out:
assert(rc != 0);
diff --git a/tools/libxl/libxl_x86_acpi.c b/tools/libxl/libxl_x86_acpi.c
index c0a6e32..1fa97ff 100644
--- a/tools/libxl/libxl_x86_acpi.c
+++ b/tools/libxl/libxl_x86_acpi.c
@@ -16,6 +16,7 @@
#include "libxl_arch.h"
#include <xen/hvm/hvm_info_table.h>
#include <xen/hvm/e820.h>
+#include "libacpi/acpi2_0.h"
#include "libacpi/libacpi.h"
#include <xc_dom.h>
@@ -236,6 +237,53 @@ out:
return rc;
}
+static void *acpi_memalign(struct acpi_ctxt *ctxt, uint32_t size,
+ uint32_t align)
+{
+ int ret;
+ void *ptr;
+
+ ret = posix_memalign(&ptr, align, size);
+ if (ret != 0 || !ptr)
+ return NULL;
+
+ return ptr;
+}
+
+int libxl__dom_build_dmar(libxl__gc *gc,
+ const libxl_domain_build_info *b_info,
+ struct xc_dom_image *dom,
+ void **data, int *len)
+{
+ struct acpi_config config = { 0 };
+ struct acpi_ctxt ctxt;
+ void *table;
+
+ if ((b_info->type != LIBXL_DOMAIN_TYPE_HVM) ||
+ (b_info->device_model_version == LIBXL_DEVICE_MODEL_VERSION_NONE) ||
+ (b_info->viommu.type != LIBXL_VIOMMU_TYPE_INTEL_VTD))
+ return 0;
+
+ ctxt.mem_ops.alloc = acpi_memalign;
+ ctxt.mem_ops.v2p = virt_to_phys;
+ ctxt.mem_ops.free = acpi_mem_free;
+
+ if (libxl_defbool_val(b_info->viommu.intremap))
+ config.iommu_intremap_supported = true;
+ if (libxl_defbool_val(b_info->viommu.u.intel_vtd.x2apic))
+ config.iommu_x2apic_supported = true;
+ config.iommu_base_addr = b_info->viommu.base_addr;
+
+ config.ioapic_id = 1; /* the IOAPIC_ID used by HVM */
+
+ table = construct_dmar(&ctxt, &config);
+ if ( !table )
+ return ERROR_NOMEM;
+ *data = table;
+ *len = ((struct acpi_header *)table)->length;
+ return 0;
+}
+
/*
* Local variables:
* mode: C
--
1.8.3.1
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |