diff --git a/docs/misc/arm/passthrough-noiommu.txt b/docs/misc/arm/passthrough-noiommu.txt new file mode 100644 index 0000000000..d9b7a9b109 --- /dev/null +++ b/docs/misc/arm/passthrough-noiommu.txt @@ -0,0 +1,29 @@ +Disable IOMMU +============= + +Add status = "disabled"; under the smmu node: + + smmu@fd800000 { + compatible = "arm,mmu-500"; + status = "disabled"; + + +Request Device Assignment without IOMMU support +=============================================== + +Add xen,force-assign-without-iommu; to the device tree snippet + + ethernet: ethernet@ff0e0000 { + compatible = "cdns,zynqmp-gem"; + xen,path = "/amba/ethernet@ff0e0000"; + xen,reg = <0x0 0xff0e0000 0x1000 0x0 0xff0e0000>; + xen,force-assign-without-iommu; + + +Request 1:1 memory mapping for the domain +========================================= + +Add direct-map under the appropriate /chosen/domU node. +If the user is using imagebuilder, you can add to boot.source: + +fdt set /chosen/domU0 direct-map <0x1> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index dd9c3b73ba..51ec7d76db 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -269,9 +269,9 @@ static void __init allocate_memory_11(struct domain *d, */ BUG_ON(!is_domain_direct_mapped(d)); - printk("Allocating 1:1 mappings totalling %ldMB for dom0:\n", + printk("Allocating 1:1 mappings totalling %ldMB for dom%u:\n", /* Don't want format this as PRIpaddr (16 digit hex) */ - (unsigned long)(kinfo->unassigned_mem >> 20)); + (unsigned long)(kinfo->unassigned_mem >> 20), d->domain_id); kinfo->mem.nr_banks = 0; @@ -2434,7 +2434,11 @@ static int __init construct_domU(struct domain *d, /* type must be set before allocate memory */ d->arch.type = kinfo.type; #endif - allocate_memory(d, &kinfo); + + if ( !is_domain_direct_mapped(d) ) + allocate_memory(d, &kinfo); + else + allocate_memory_11(d, &kinfo); rc = prepare_dtb_domU(d, &kinfo); if ( rc < 0 ) @@ -2454,6 +2458,8 @@ void __init create_domUs(void) { struct dt_device_node *node; const struct dt_device_node *chosen = dt_find_node_by_path("/chosen"); + int rc; + u32 direct_map = 0; BUG_ON(chosen == NULL); dt_for_each_child_node(chosen, node) @@ -2474,7 +2480,9 @@ void __init create_domUs(void) panic("Missing property 'cpus' for domain %s\n", dt_node_name(node)); - if ( dt_find_compatible_node(node, NULL, "multiboot,device-tree") ) + rc = dt_property_read_u32(node, "direct-map", &direct_map); + if ( dt_find_compatible_node(node, NULL, "multiboot,device-tree") && + (!rc || !direct_map) ) d_cfg.flags |= XEN_DOMCTL_CDF_iommu; if ( !dt_property_read_u32(node, "nr_spis", &d_cfg.arch.nr_spis) ) @@ -2495,6 +2503,7 @@ void __init create_domUs(void) panic("Error creating domain %s\n", dt_node_name(node)); d->is_console = true; + d->arch.direct_map = (rc && direct_map != 0); if ( construct_domU(d, node) != 0 ) panic("Could not set up domain %s\n", dt_node_name(node)); @@ -2524,6 +2533,7 @@ int __init construct_dom0(struct domain *d) iommu_hwdom_init(d); + d->arch.direct_map = true; d->max_pages = ~0U; kinfo.unassigned_mem = dom0_mem; diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h index f3f3fb7d7f..8b5e1542e5 100644 --- a/xen/include/asm-arm/domain.h +++ b/xen/include/asm-arm/domain.h @@ -32,7 +32,7 @@ enum domain_type { #endif /* The hardware domain has always its memory direct mapped. */ -#define is_domain_direct_mapped(d) ((d) == hardware_domain) +#define is_domain_direct_mapped(d) ((d)->arch.direct_map != false) struct vtimer { struct vcpu *v; @@ -101,6 +101,8 @@ struct arch_domain #ifdef CONFIG_TEE void *tee; #endif + + bool direct_map; } __cacheline_aligned; struct arch_vcpu