iommu/s390: Add support for iommu_device handling
Add support for the iommu_device_register interface to make the s390 hardware iommus visible to the iommu core and in sysfs. Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
This commit is contained in:
parent
ef954844c7
commit
f42c223514
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <asm-generic/pci.h>
|
||||
#include <asm/pci_clp.h>
|
||||
#include <asm/pci_debug.h>
|
||||
|
@ -122,6 +123,8 @@ struct zpci_dev {
|
|||
unsigned long iommu_pages;
|
||||
unsigned int next_bit;
|
||||
|
||||
struct iommu_device iommu_dev; /* IOMMU core handle */
|
||||
|
||||
char res_name[16];
|
||||
struct zpci_bar_struct bars[PCI_BAR_COUNT];
|
||||
|
||||
|
@ -174,6 +177,10 @@ int clp_enable_fh(struct zpci_dev *, u8);
|
|||
int clp_disable_fh(struct zpci_dev *);
|
||||
int clp_get_state(u32 fid, enum zpci_state *state);
|
||||
|
||||
/* IOMMU Interface */
|
||||
int zpci_init_iommu(struct zpci_dev *zdev);
|
||||
void zpci_destroy_iommu(struct zpci_dev *zdev);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* Error handling and recovery */
|
||||
void zpci_event_error(void *);
|
||||
|
|
|
@ -776,6 +776,7 @@ void pcibios_remove_bus(struct pci_bus *bus)
|
|||
|
||||
zpci_exit_slot(zdev);
|
||||
zpci_cleanup_bus_resources(zdev);
|
||||
zpci_destroy_iommu(zdev);
|
||||
zpci_free_domain(zdev);
|
||||
|
||||
spin_lock(&zpci_list_lock);
|
||||
|
@ -848,11 +849,15 @@ int zpci_create_device(struct zpci_dev *zdev)
|
|||
if (rc)
|
||||
goto out;
|
||||
|
||||
rc = zpci_init_iommu(zdev);
|
||||
if (rc)
|
||||
goto out_free;
|
||||
|
||||
mutex_init(&zdev->lock);
|
||||
if (zdev->state == ZPCI_FN_STATE_CONFIGURED) {
|
||||
rc = zpci_enable_device(zdev);
|
||||
if (rc)
|
||||
goto out_free;
|
||||
goto out_destroy_iommu;
|
||||
}
|
||||
rc = zpci_scan_bus(zdev);
|
||||
if (rc)
|
||||
|
@ -869,6 +874,8 @@ int zpci_create_device(struct zpci_dev *zdev)
|
|||
out_disable:
|
||||
if (zdev->state == ZPCI_FN_STATE_ONLINE)
|
||||
zpci_disable_device(zdev);
|
||||
out_destroy_iommu:
|
||||
zpci_destroy_iommu(zdev);
|
||||
out_free:
|
||||
zpci_free_domain(zdev);
|
||||
out:
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
#define S390_IOMMU_PGSIZES (~0xFFFUL)
|
||||
|
||||
static struct iommu_ops s390_iommu_ops;
|
||||
|
||||
struct s390_domain {
|
||||
struct iommu_domain domain;
|
||||
struct list_head devices;
|
||||
|
@ -166,11 +168,13 @@ static void s390_iommu_detach_device(struct iommu_domain *domain,
|
|||
static int s390_iommu_add_device(struct device *dev)
|
||||
{
|
||||
struct iommu_group *group = iommu_group_get_for_dev(dev);
|
||||
struct zpci_dev *zdev = to_pci_dev(dev)->sysdata;
|
||||
|
||||
if (IS_ERR(group))
|
||||
return PTR_ERR(group);
|
||||
|
||||
iommu_group_put(group);
|
||||
iommu_device_link(&zdev->iommu_dev, dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -197,6 +201,7 @@ static void s390_iommu_remove_device(struct device *dev)
|
|||
s390_iommu_detach_device(domain, dev);
|
||||
}
|
||||
|
||||
iommu_device_unlink(&zdev->iommu_dev, dev);
|
||||
iommu_group_remove_device(dev);
|
||||
}
|
||||
|
||||
|
@ -327,6 +332,36 @@ static size_t s390_iommu_unmap(struct iommu_domain *domain,
|
|||
return size;
|
||||
}
|
||||
|
||||
int zpci_init_iommu(struct zpci_dev *zdev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = iommu_device_sysfs_add(&zdev->iommu_dev, NULL, NULL,
|
||||
"s390-iommu.%08x", zdev->fid);
|
||||
if (rc)
|
||||
goto out_err;
|
||||
|
||||
iommu_device_set_ops(&zdev->iommu_dev, &s390_iommu_ops);
|
||||
|
||||
rc = iommu_device_register(&zdev->iommu_dev);
|
||||
if (rc)
|
||||
goto out_sysfs;
|
||||
|
||||
return 0;
|
||||
|
||||
out_sysfs:
|
||||
iommu_device_sysfs_remove(&zdev->iommu_dev);
|
||||
|
||||
out_err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
void zpci_destroy_iommu(struct zpci_dev *zdev)
|
||||
{
|
||||
iommu_device_unregister(&zdev->iommu_dev);
|
||||
iommu_device_sysfs_remove(&zdev->iommu_dev);
|
||||
}
|
||||
|
||||
static struct iommu_ops s390_iommu_ops = {
|
||||
.capable = s390_iommu_capable,
|
||||
.domain_alloc = s390_domain_alloc,
|
||||
|
|
Loading…
Reference in New Issue