diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-14 12:41:31 +0100 |
---|---|---|
committer | Joerg Roedel <joerg.roedel@amd.com> | 2011-12-14 12:52:09 +0100 |
commit | a06ec394c9318e2ee9209ca3c106d3fa6fbfeb00 (patch) | |
tree | f94f71b5a542b42ecea60e6f903e3f19e5b2eada /drivers/iommu/amd_iommu.c | |
parent | 175d6146738b3d04e1adcaa4a971a3b2b0dbd8af (diff) | |
parent | 6c274d1cd5b3aa0834e9f0c3f58038f42278ff8c (diff) |
Merge branch 'iommu/page-sizes' into x86/amd
Conflicts:
drivers/iommu/amd_iommu.c
Diffstat (limited to 'drivers/iommu/amd_iommu.c')
-rw-r--r-- | drivers/iommu/amd_iommu.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 2a46b1d7a60..a7cbcd46af9 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c @@ -44,6 +44,24 @@ #define LOOP_TIMEOUT 100000 +/* + * This bitmap is used to advertise the page sizes our hardware support + * to the IOMMU core, which will then use this information to split + * physically contiguous memory regions it is mapping into page sizes + * that we support. + * + * Traditionally the IOMMU core just handed us the mappings directly, + * after making sure the size is an order of a 4KiB page and that the + * mapping has natural alignment. + * + * To retain this behavior, we currently advertise that we support + * all page sizes that are an order of 4KiB. + * + * If at some point we'd like to utilize the IOMMU core's new behavior, + * we could change this to advertise the real page sizes we support. + */ +#define AMD_IOMMU_PGSIZES (~0xFFFUL) + static DEFINE_RWLOCK(amd_iommu_devtable_lock); /* A list of preallocated protection domains */ @@ -3093,9 +3111,8 @@ static int amd_iommu_attach_device(struct iommu_domain *dom, } static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, - phys_addr_t paddr, int gfp_order, int iommu_prot) + phys_addr_t paddr, size_t page_size, int iommu_prot) { - unsigned long page_size = 0x1000UL << gfp_order; struct protection_domain *domain = dom->priv; int prot = 0; int ret; @@ -3115,24 +3132,22 @@ static int amd_iommu_map(struct iommu_domain *dom, unsigned long iova, return ret; } -static int amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, - int gfp_order) +static size_t amd_iommu_unmap(struct iommu_domain *dom, unsigned long iova, + size_t page_size) { struct protection_domain *domain = dom->priv; - unsigned long page_size, unmap_size; + size_t unmap_size; if (domain->mode == PAGE_MODE_NONE) return -EINVAL; - page_size = 0x1000UL << gfp_order; - mutex_lock(&domain->api_lock); unmap_size = iommu_unmap_page(domain, iova, page_size); mutex_unlock(&domain->api_lock); domain_flush_tlb_pde(domain); - return get_order(unmap_size); + return unmap_size; } static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, @@ -3182,6 +3197,7 @@ static struct iommu_ops amd_iommu_ops = { .unmap = amd_iommu_unmap, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, + .pgsize_bitmap = AMD_IOMMU_PGSIZES, }; /***************************************************************************** |