Files
agnos-kernel-sdm845/include/linux/dma-mapping-fast.h
Mitchel Humpherys 5c704e0c85 iommu/io-pgtable-fast: Prove correctness of TLB maintenance
A common software error when it comes to page table code is missing TLB
maintenance.  Add some checks to the io-pgtable-fast code to detect when
an address that might be stale in the TLB is being re-used.  This can be
accomplished by writing a "stale TLB" flag value to the reserved bits of
the PTE during unmap and then removing the flag value when the TLBs are
invalidated (by sweeping the entire page table).  That way, whenever we
map we can know that there might be a stale TLB in the location being
mapped into if it contains the "stale TLB" flag value.

CRs-Fixed: 997751
Change-Id: Icf9c1e41977cb71e8b137190adb3b4a201c339da
Signed-off-by: Mitchel Humpherys <mitchelh@codeaurora.org>
Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
2016-10-12 22:19:19 -07:00

58 lines
1.5 KiB
C

/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __LINUX_DMA_MAPPING_FAST_H
#define __LINUX_DMA_MAPPING_FAST_H
#include <linux/iommu.h>
#include <linux/io-pgtable-fast.h>
struct dma_fast_smmu_mapping {
struct device *dev;
struct iommu_domain *domain;
dma_addr_t base;
size_t size;
size_t num_4k_pages;
unsigned int bitmap_size;
unsigned long *bitmap;
unsigned long next_start;
unsigned long upcoming_stale_bit;
bool have_stale_tlbs;
dma_addr_t pgtbl_dma_handle;
av8l_fast_iopte *pgtbl_pmds;
spinlock_t lock;
struct notifier_block notifier;
};
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
int fast_smmu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping);
void fast_smmu_detach_device(struct device *dev,
struct dma_iommu_mapping *mapping);
#else
static inline int fast_smmu_attach_device(struct device *dev,
struct dma_iommu_mapping *mapping)
{
return -ENODEV;
}
static inline void fast_smmu_detach_device(struct device *dev,
struct dma_iommu_mapping *mapping)
{
}
#endif
#endif /* __LINUX_DMA_MAPPING_FAST_H */