Commit 0bae49b2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'iommu-fixes-v3.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu

Pull iommu fixes from Joerg Roedel:
 "A couple of fixes for the Freescale PAMU driver queued up:

   - fix PAMU window size check.
   - fix the device domain attach condition.
   - fix the error condition during iommu group"

* tag 'iommu-fixes-v3.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu:
  iommu/fsl: Fix the error condition during iommu group
  iommu/fsl: Fix the device domain attach condition.
  iommu/fsl: Fix PAMU window size check.
parents 084c9cac 3170447c
...@@ -170,10 +170,10 @@ int pamu_disable_liodn(int liodn) ...@@ -170,10 +170,10 @@ int pamu_disable_liodn(int liodn)
static unsigned int map_addrspace_size_to_wse(phys_addr_t addrspace_size) static unsigned int map_addrspace_size_to_wse(phys_addr_t addrspace_size)
{ {
/* Bug if not a power of 2 */ /* Bug if not a power of 2 */
BUG_ON(!is_power_of_2(addrspace_size)); BUG_ON((addrspace_size & (addrspace_size - 1)));
/* window size is 2^(WSE+1) bytes */ /* window size is 2^(WSE+1) bytes */
return __ffs(addrspace_size) - 1; return fls64(addrspace_size) - 2;
} }
/* Derive the PAACE window count encoding for the subwindow count */ /* Derive the PAACE window count encoding for the subwindow count */
...@@ -351,7 +351,7 @@ int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size, ...@@ -351,7 +351,7 @@ int pamu_config_ppaace(int liodn, phys_addr_t win_addr, phys_addr_t win_size,
struct paace *ppaace; struct paace *ppaace;
unsigned long fspi; unsigned long fspi;
if (!is_power_of_2(win_size) || win_size < PAMU_PAGE_SIZE) { if ((win_size & (win_size - 1)) || win_size < PAMU_PAGE_SIZE) {
pr_debug("window size too small or not a power of two %llx\n", win_size); pr_debug("window size too small or not a power of two %llx\n", win_size);
return -EINVAL; return -EINVAL;
} }
...@@ -464,7 +464,7 @@ int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin, ...@@ -464,7 +464,7 @@ int pamu_config_spaace(int liodn, u32 subwin_cnt, u32 subwin,
return -ENOENT; return -ENOENT;
} }
if (!is_power_of_2(subwin_size) || subwin_size < PAMU_PAGE_SIZE) { if ((subwin_size & (subwin_size - 1)) || subwin_size < PAMU_PAGE_SIZE) {
pr_debug("subwindow size out of range, or not a power of 2\n"); pr_debug("subwindow size out of range, or not a power of 2\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -301,7 +301,7 @@ static int check_size(u64 size, dma_addr_t iova) ...@@ -301,7 +301,7 @@ static int check_size(u64 size, dma_addr_t iova)
* Size must be a power of two and at least be equal * Size must be a power of two and at least be equal
* to PAMU page size. * to PAMU page size.
*/ */
if (!is_power_of_2(size) || size < PAMU_PAGE_SIZE) { if ((size & (size - 1)) || size < PAMU_PAGE_SIZE) {
pr_debug("%s: size too small or not a power of two\n", __func__); pr_debug("%s: size too small or not a power of two\n", __func__);
return -EINVAL; return -EINVAL;
} }
...@@ -335,11 +335,6 @@ static struct fsl_dma_domain *iommu_alloc_dma_domain(void) ...@@ -335,11 +335,6 @@ static struct fsl_dma_domain *iommu_alloc_dma_domain(void)
return domain; return domain;
} }
static inline struct device_domain_info *find_domain(struct device *dev)
{
return dev->archdata.iommu_domain;
}
static void remove_device_ref(struct device_domain_info *info, u32 win_cnt) static void remove_device_ref(struct device_domain_info *info, u32 win_cnt)
{ {
unsigned long flags; unsigned long flags;
...@@ -380,7 +375,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d ...@@ -380,7 +375,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* Check here if the device is already attached to domain or not. * Check here if the device is already attached to domain or not.
* If the device is already attached to a domain detach it. * If the device is already attached to a domain detach it.
*/ */
old_domain_info = find_domain(dev); old_domain_info = dev->archdata.iommu_domain;
if (old_domain_info && old_domain_info->domain != dma_domain) { if (old_domain_info && old_domain_info->domain != dma_domain) {
spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags);
detach_device(dev, old_domain_info->domain); detach_device(dev, old_domain_info->domain);
...@@ -399,7 +394,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d ...@@ -399,7 +394,7 @@ static void attach_device(struct fsl_dma_domain *dma_domain, int liodn, struct d
* the info for the first LIODN as all * the info for the first LIODN as all
* LIODNs share the same domain * LIODNs share the same domain
*/ */
if (!old_domain_info) if (!dev->archdata.iommu_domain)
dev->archdata.iommu_domain = info; dev->archdata.iommu_domain = info;
spin_unlock_irqrestore(&device_domain_lock, flags); spin_unlock_irqrestore(&device_domain_lock, flags);
...@@ -1042,12 +1037,15 @@ static struct iommu_group *get_pci_device_group(struct pci_dev *pdev) ...@@ -1042,12 +1037,15 @@ static struct iommu_group *get_pci_device_group(struct pci_dev *pdev)
group = get_shared_pci_device_group(pdev); group = get_shared_pci_device_group(pdev);
} }
if (!group)
group = ERR_PTR(-ENODEV);
return group; return group;
} }
static int fsl_pamu_add_device(struct device *dev) static int fsl_pamu_add_device(struct device *dev)
{ {
struct iommu_group *group = NULL; struct iommu_group *group = ERR_PTR(-ENODEV);
struct pci_dev *pdev; struct pci_dev *pdev;
const u32 *prop; const u32 *prop;
int ret, len; int ret, len;
...@@ -1070,7 +1068,7 @@ static int fsl_pamu_add_device(struct device *dev) ...@@ -1070,7 +1068,7 @@ static int fsl_pamu_add_device(struct device *dev)
group = get_device_iommu_group(dev); group = get_device_iommu_group(dev);
} }
if (!group || IS_ERR(group)) if (IS_ERR(group))
return PTR_ERR(group); return PTR_ERR(group);
ret = iommu_group_add_device(group, dev); ret = iommu_group_add_device(group, dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment