diff options
Diffstat (limited to 'drivers/iommu/amd/iommu.c')
| -rw-r--r-- | drivers/iommu/amd/iommu.c | 61 | 
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index d3b39d0416fa..cbeaab55c0db 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -767,7 +767,7 @@ EXPORT_SYMBOL(amd_iommu_register_ga_log_notifier);  static void iommu_poll_ga_log(struct amd_iommu *iommu)  { -	u32 head, tail, cnt = 0; +	u32 head, tail;  	if (iommu->ga_log == NULL)  		return; @@ -780,7 +780,6 @@ static void iommu_poll_ga_log(struct amd_iommu *iommu)  		u64 log_entry;  		raw = (u64 *)(iommu->ga_log + head); -		cnt++;  		/* Avoid memcpy function-call overhead */  		log_entry = *raw; @@ -812,10 +811,10 @@ static void  amd_iommu_set_pci_msi_domain(struct device *dev, struct amd_iommu *iommu)  {  	if (!irq_remapping_enabled || !dev_is_pci(dev) || -	    pci_dev_has_special_msi_domain(to_pci_dev(dev))) +	    !pci_dev_has_default_msi_parent_domain(to_pci_dev(dev)))  		return; -	dev_set_msi_domain(dev, iommu->msi_domain); +	dev_set_msi_domain(dev, iommu->ir_domain);  }  #else /* CONFIG_IRQ_REMAP */ @@ -2155,21 +2154,13 @@ static void amd_iommu_detach_device(struct iommu_domain *dom,  static int amd_iommu_attach_device(struct iommu_domain *dom,  				   struct device *dev)  { +	struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);  	struct protection_domain *domain = to_pdomain(dom); -	struct iommu_dev_data *dev_data; -	struct amd_iommu *iommu; +	struct amd_iommu *iommu = rlookup_amd_iommu(dev);  	int ret; -	if (!check_device(dev)) -		return -EINVAL; - -	dev_data = dev_iommu_priv_get(dev);  	dev_data->defer_attach = false; -	iommu = rlookup_amd_iommu(dev); -	if (!iommu) -		return -EINVAL; -  	if (dev_data->domain)  		detach_device(dev); @@ -2286,6 +2277,8 @@ static bool amd_iommu_capable(struct device *dev, enum iommu_cap cap)  		return false;  	case IOMMU_CAP_PRE_BOOT_PROTECTION:  		return amdr_ivrs_remap_support; +	case IOMMU_CAP_ENFORCE_CACHE_COHERENCY: +		return true;  	default:  		break;  	} @@ -3294,17 +3287,9 @@ static int irq_remapping_alloc(struct irq_domain *domain, unsigned int virq,  	if (!info)  		return -EINVAL; -	if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI && -	    info->type != X86_IRQ_ALLOC_TYPE_PCI_MSIX) +	if (nr_irqs > 1 && info->type != X86_IRQ_ALLOC_TYPE_PCI_MSI)  		return -EINVAL; -	/* -	 * With IRQ remapping enabled, don't need contiguous CPU vectors -	 * to support multiple MSI interrupts. -	 */ -	if (info->type == X86_IRQ_ALLOC_TYPE_PCI_MSI) -		info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS; -  	sbdf = get_devid(info);  	if (sbdf < 0)  		return -EINVAL; @@ -3656,6 +3641,21 @@ static struct irq_chip amd_ir_chip = {  	.irq_compose_msi_msg	= ir_compose_msi_msg,  }; +static const struct msi_parent_ops amdvi_msi_parent_ops = { +	.supported_flags	= X86_VECTOR_MSI_FLAGS_SUPPORTED | +				  MSI_FLAG_MULTI_PCI_MSI | +				  MSI_FLAG_PCI_IMS, +	.prefix			= "IR-", +	.init_dev_msi_info	= msi_parent_init_dev_msi_info, +}; + +static const struct msi_parent_ops virt_amdvi_msi_parent_ops = { +	.supported_flags	= X86_VECTOR_MSI_FLAGS_SUPPORTED | +				  MSI_FLAG_MULTI_PCI_MSI, +	.prefix			= "vIR-", +	.init_dev_msi_info	= msi_parent_init_dev_msi_info, +}; +  int amd_iommu_create_irq_domain(struct amd_iommu *iommu)  {  	struct fwnode_handle *fn; @@ -3663,16 +3663,21 @@ int amd_iommu_create_irq_domain(struct amd_iommu *iommu)  	fn = irq_domain_alloc_named_id_fwnode("AMD-IR", iommu->index);  	if (!fn)  		return -ENOMEM; -	iommu->ir_domain = irq_domain_create_tree(fn, &amd_ir_domain_ops, iommu); +	iommu->ir_domain = irq_domain_create_hierarchy(arch_get_ir_parent_domain(), 0, 0, +						       fn, &amd_ir_domain_ops, iommu);  	if (!iommu->ir_domain) {  		irq_domain_free_fwnode(fn);  		return -ENOMEM;  	} -	iommu->ir_domain->parent = arch_get_ir_parent_domain(); -	iommu->msi_domain = arch_create_remap_msi_irq_domain(iommu->ir_domain, -							     "AMD-IR-MSI", -							     iommu->index); +	irq_domain_update_bus_token(iommu->ir_domain,  DOMAIN_BUS_AMDVI); +	iommu->ir_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; + +	if (amd_iommu_np_cache) +		iommu->ir_domain->msi_parent_ops = &virt_amdvi_msi_parent_ops; +	else +		iommu->ir_domain->msi_parent_ops = &amdvi_msi_parent_ops; +  	return 0;  }  |