|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 17/20] xen/arm: vsmmuv3: Alloc virq for virtual SMMUv3
From: Rahul Singh <rahul.singh@xxxxxxx>
Alloc and reserve virq for event queue and global error to send event to
guests. Also Modify the libxl to accomadate the new define virq.
Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx>
Signed-off-by: Milan Djokic <milan_djokic@xxxxxxxx>
---
tools/libs/light/libxl_arm.c | 28 ++++++++++++++++++++++++--
xen/arch/arm/dom0less-build.c | 17 ++++++++++++++++
xen/drivers/passthrough/arm/vsmmu-v3.c | 13 ++++++++++++
3 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/tools/libs/light/libxl_arm.c b/tools/libs/light/libxl_arm.c
index c8255d8d4f..55beda8c0e 100644
--- a/tools/libs/light/libxl_arm.c
+++ b/tools/libs/light/libxl_arm.c
@@ -86,8 +86,8 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
{
uint32_t nr_spis = 0, cfg_nr_spis = d_config->b_info.arch_arm.nr_spis;
unsigned int i;
- uint32_t vuart_irq, virtio_irq = 0;
- bool vuart_enabled = false, virtio_enabled = false;
+ uint32_t vuart_irq, virtio_irq = 0, vsmmu_irq = 0;
+ bool vuart_enabled = false, virtio_enabled = false, vsmmu_enabled = false;
uint64_t virtio_mmio_base = GUEST_VIRTIO_MMIO_BASE;
uint32_t virtio_mmio_irq = GUEST_VIRTIO_MMIO_SPI_FIRST;
int rc;
@@ -102,6 +102,16 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
vuart_enabled = true;
}
+ /*
+ * If smmuv3 viommu is enabled then increment the nr_spis to allow
allocation
+ * of SPI VIRQ for VSMMU.
+ */
+ if (d_config->b_info.arch_arm.viommu_type == LIBXL_VIOMMU_TYPE_SMMUV3) {
+ nr_spis += (GUEST_VSMMU_SPI - 32) + 1;
+ vsmmu_irq = GUEST_VSMMU_SPI;
+ vsmmu_enabled = true;
+ }
+
for (i = 0; i < d_config->num_disks; i++) {
libxl_device_disk *disk = &d_config->disks[i];
@@ -170,6 +180,11 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc,
return ERROR_FAIL;
}
+ if (vsmmu_enabled && irq == vsmmu_irq) {
+ LOG(ERROR, "Physical IRQ %u conflicting with vSMMUv3 SPI\n", irq);
+ return ERROR_FAIL;
+ }
+
if (irq < 32)
continue;
@@ -893,6 +908,7 @@ static int make_vsmmuv3_node(libxl__gc *gc, void *fdt,
{
int res;
const char *name = GCSPRINTF("iommu@%llx", GUEST_VSMMUV3_BASE);
+ gic_interrupt intr;
res = fdt_begin_node(fdt, name);
if (res) return res;
@@ -911,6 +927,14 @@ static int make_vsmmuv3_node(libxl__gc *gc, void *fdt,
res = fdt_property_cell(fdt, "#iommu-cells", 1);
if (res) return res;
+ res = fdt_property_string(fdt, "interrupt-names", "combined");
+ if (res) return res;
+
+ set_interrupt(intr, GUEST_VSMMU_SPI, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
+
+ res = fdt_property_interrupts(gc, fdt, &intr, 1);
+ if (res) return res;
+
res = fdt_end_node(fdt);
if (res) return res;
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 1e526c10de..66ef3dfa1f 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -224,6 +224,7 @@ static int __init make_vsmmuv3_node(const struct
kernel_info *kinfo)
char buf[24];
__be32 reg[GUEST_ROOT_ADDRESS_CELLS + GUEST_ROOT_SIZE_CELLS];
__be32 *cells;
+ gic_interrupt_t intr;
void *fdt = kinfo->fdt;
snprintf(buf, sizeof(buf), "iommu@%llx", GUEST_VSMMUV3_BASE);
@@ -254,6 +255,22 @@ static int __init make_vsmmuv3_node(const struct
kernel_info *kinfo)
if ( res )
return res;
+ res = fdt_property_string(fdt, "interrupt-names", "combined");
+ if ( res )
+ return res;
+
+ set_interrupt(intr, GUEST_VSMMU_SPI, 0xf, DT_IRQ_TYPE_LEVEL_HIGH);
+
+ res = fdt_property(kinfo->fdt, "interrupts",
+ intr, sizeof(intr));
+ if ( res )
+ return res;
+
+ res = fdt_property_cell(kinfo->fdt, "interrupt-parent",
+ kinfo->phandle_intc);
+ if ( res )
+ return res;
+
res = fdt_end_node(fdt);
return res;
diff --git a/xen/drivers/passthrough/arm/vsmmu-v3.c
b/xen/drivers/passthrough/arm/vsmmu-v3.c
index 7a6c18df53..a5b9700369 100644
--- a/xen/drivers/passthrough/arm/vsmmu-v3.c
+++ b/xen/drivers/passthrough/arm/vsmmu-v3.c
@@ -733,6 +733,7 @@ static const struct mmio_handler_ops vsmmuv3_mmio_handler =
{
static int vsmmuv3_init_single(struct domain *d, paddr_t addr,
paddr_t size, uint32_t virq)
{
+ int ret;
struct virt_smmu *smmu;
smmu = xzalloc(struct virt_smmu);
@@ -748,12 +749,24 @@ static int vsmmuv3_init_single(struct domain *d, paddr_t
addr,
spin_lock_init(&smmu->cmd_queue_lock);
+ ret = vgic_reserve_virq(d, virq);
+ if ( !ret )
+ {
+ ret = -EINVAL;
+ goto out;
+ }
+
register_mmio_handler(d, &vsmmuv3_mmio_handler, addr, size, smmu);
/* Register the vIOMMU to be able to clean it up later. */
list_add_tail(&smmu->viommu_list, &d->arch.viommu_list);
return 0;
+
+out:
+ xfree(smmu);
+ vgic_free_virq(d, virq);
+ return ret;
}
int domain_vsmmuv3_init(struct domain *d)
--
2.43.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |