Allow clients to specify the IOVA range for fastmap clients via the DOMAIN_ATTR_GEOMETRY domain attribute. Presently fastmap only allocates page tables for the IOVA range specified during the create mapping call. However clients may want to use IOVA addresses outside this range, such as for their calls to iommu_map. So allow clients to extend the available IOVA space by setting the DOMAIN_ATTR_GEOMETRY domain attribute's iommu_domain_geometry.aperture_start to the new start address of the IOVA space and by setting iommu_domain_geometry.aperture_end to the new end address of the IOVA space. The new IOVA space created by iommu_domain_geometry.aperture_start and iommu_domain_geometry.aperture_end will be a superset of the IOVA range which was created through the create mapping call. The DOMAIN_ATTR_GEOMETRY domain attribute can only be set before attaching. Calls to set the DOMAIN_ATTR_GEOMETRY domain attribute can only be used to extend the IOVA space, it cannot shrink the range. Note that extending the IOVA range will not change the range of IOVA addresses which will be available to the DMA APIs. CRs-Fixed: 2035925 Change-Id: Ib389e019a022d98417884002de08115fb0fc9384 Signed-off-by: Liam Mark <lmark@codeaurora.org> [guptap@codeaurora.org: update geometry.aperture with mapping] Signed-off-by: Prakash Gupta <guptap@codeaurora.org>
105 lines
2.7 KiB
C
105 lines
2.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef __LINUX_IO_PGTABLE_FAST_H
|
|
#define __LINUX_IO_PGTABLE_FAST_H
|
|
|
|
#include <linux/notifier.h>
|
|
|
|
/*
|
|
* This ought to be private to io-pgtable-fast, but dma-mapping-fast
|
|
* currently requires it for a debug usecase.
|
|
*/
|
|
typedef u64 av8l_fast_iopte;
|
|
|
|
struct io_pgtable_ops;
|
|
|
|
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST
|
|
|
|
int av8l_fast_map_public(struct io_pgtable_ops *ops, unsigned long iova,
|
|
phys_addr_t paddr, size_t size, int prot);
|
|
|
|
void av8l_fast_unmap_public(struct io_pgtable_ops *ops, unsigned long iova,
|
|
size_t size);
|
|
|
|
int av8l_fast_map_sg_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova, struct scatterlist *sgl,
|
|
unsigned int nents, int prot, size_t *size);
|
|
|
|
bool av8l_fast_iova_coherent_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova);
|
|
|
|
phys_addr_t av8l_fast_iova_to_phys_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova);
|
|
#else
|
|
static inline int
|
|
av8l_fast_map_public(struct io_pgtable_ops *ops, unsigned long iova,
|
|
phys_addr_t paddr, size_t size, int prot)
|
|
{
|
|
return -EINVAL;
|
|
}
|
|
static inline void av8l_fast_unmap_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova, size_t size)
|
|
{
|
|
}
|
|
|
|
static inline int av8l_fast_map_sg_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova, struct scatterlist *sgl,
|
|
unsigned int nents, int prot, size_t *size)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static inline bool av8l_fast_iova_coherent_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova)
|
|
{
|
|
return false;
|
|
}
|
|
static inline phys_addr_t
|
|
av8l_fast_iova_to_phys_public(struct io_pgtable_ops *ops,
|
|
unsigned long iova)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif /* CONFIG_IOMMU_IO_PGTABLE_FAST */
|
|
|
|
|
|
/* events for notifiers passed to av8l_register_notify */
|
|
#define MAPPED_OVER_STALE_TLB 1
|
|
|
|
|
|
#ifdef CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB
|
|
/*
|
|
* Doesn't matter what we use as long as bit 0 is unset. The reason why we
|
|
* need a different value at all is that there are certain hardware
|
|
* platforms with erratum that require that a PTE actually be zero'd out
|
|
* and not just have its valid bit unset.
|
|
*/
|
|
#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0xa
|
|
|
|
void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops, u64 base,
|
|
u64 start, u64 end, bool skip_sync);
|
|
void av8l_register_notify(struct notifier_block *nb);
|
|
|
|
#else /* !CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */
|
|
|
|
#define AV8L_FAST_PTE_UNMAPPED_NEED_TLBI 0
|
|
|
|
static inline void av8l_fast_clear_stale_ptes(struct io_pgtable_ops *ops,
|
|
u64 base,
|
|
u64 start,
|
|
u64 end,
|
|
bool skip_sync)
|
|
{
|
|
}
|
|
|
|
static inline void av8l_register_notify(struct notifier_block *nb)
|
|
{
|
|
}
|
|
|
|
#endif /* CONFIG_IOMMU_IO_PGTABLE_FAST_PROVE_TLB */
|
|
|
|
#endif /* __LINUX_IO_PGTABLE_FAST_H */
|