mirror of
https://github.com/qemu/qemu.git
synced 2025-08-14 11:43:46 +00:00
iommu: Add IOMMU index concept to IOMMU API
If an IOMMU supports mappings that care about the memory transaction attributes, then it no longer has a unique address -> output mapping, but more than one. We can represent these using an IOMMU index, analogous to TCG's mmu indexes. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-id: 20180604152941.20374-2-peter.maydell@linaro.org
This commit is contained in:
parent
2151b044fd
commit
21f402093c
@ -206,6 +206,20 @@ enum IOMMUMemoryRegionAttr {
|
|||||||
* to report whenever mappings are changed, by calling
|
* to report whenever mappings are changed, by calling
|
||||||
* memory_region_notify_iommu() (or, if necessary, by calling
|
* memory_region_notify_iommu() (or, if necessary, by calling
|
||||||
* memory_region_notify_one() for each registered notifier).
|
* memory_region_notify_one() for each registered notifier).
|
||||||
|
*
|
||||||
|
* Conceptually an IOMMU provides a mapping from input address
|
||||||
|
* to an output TLB entry. If the IOMMU is aware of memory transaction
|
||||||
|
* attributes and the output TLB entry depends on the transaction
|
||||||
|
* attributes, we represent this using IOMMU indexes. Each index
|
||||||
|
* selects a particular translation table that the IOMMU has:
|
||||||
|
* @attrs_to_index returns the IOMMU index for a set of transaction attributes
|
||||||
|
* @translate takes an input address and an IOMMU index
|
||||||
|
* and the mapping returned can only depend on the input address and the
|
||||||
|
* IOMMU index.
|
||||||
|
*
|
||||||
|
* Most IOMMUs don't care about the transaction attributes and support
|
||||||
|
* only a single IOMMU index. A more complex IOMMU might have one index
|
||||||
|
* for secure transactions and one for non-secure transactions.
|
||||||
*/
|
*/
|
||||||
typedef struct IOMMUMemoryRegionClass {
|
typedef struct IOMMUMemoryRegionClass {
|
||||||
/* private */
|
/* private */
|
||||||
@ -290,6 +304,29 @@ typedef struct IOMMUMemoryRegionClass {
|
|||||||
*/
|
*/
|
||||||
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
|
int (*get_attr)(IOMMUMemoryRegion *iommu, enum IOMMUMemoryRegionAttr attr,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
/* Return the IOMMU index to use for a given set of transaction attributes.
|
||||||
|
*
|
||||||
|
* Optional method: if an IOMMU only supports a single IOMMU index then
|
||||||
|
* the default implementation of memory_region_iommu_attrs_to_index()
|
||||||
|
* will return 0.
|
||||||
|
*
|
||||||
|
* The indexes supported by an IOMMU must be contiguous, starting at 0.
|
||||||
|
*
|
||||||
|
* @iommu: the IOMMUMemoryRegion
|
||||||
|
* @attrs: memory transaction attributes
|
||||||
|
*/
|
||||||
|
int (*attrs_to_index)(IOMMUMemoryRegion *iommu, MemTxAttrs attrs);
|
||||||
|
|
||||||
|
/* Return the number of IOMMU indexes this IOMMU supports.
|
||||||
|
*
|
||||||
|
* Optional method: if this method is not provided, then
|
||||||
|
* memory_region_iommu_num_indexes() will return 1, indicating that
|
||||||
|
* only a single IOMMU index is supported.
|
||||||
|
*
|
||||||
|
* @iommu: the IOMMUMemoryRegion
|
||||||
|
*/
|
||||||
|
int (*num_indexes)(IOMMUMemoryRegion *iommu);
|
||||||
} IOMMUMemoryRegionClass;
|
} IOMMUMemoryRegionClass;
|
||||||
|
|
||||||
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
|
typedef struct CoalescedMemoryRange CoalescedMemoryRange;
|
||||||
@ -1054,6 +1091,24 @@ int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
|
|||||||
enum IOMMUMemoryRegionAttr attr,
|
enum IOMMUMemoryRegionAttr attr,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memory_region_iommu_attrs_to_index: return the IOMMU index to
|
||||||
|
* use for translations with the given memory transaction attributes.
|
||||||
|
*
|
||||||
|
* @iommu_mr: the memory region
|
||||||
|
* @attrs: the memory transaction attributes
|
||||||
|
*/
|
||||||
|
int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
|
||||||
|
MemTxAttrs attrs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* memory_region_iommu_num_indexes: return the total number of IOMMU
|
||||||
|
* indexes that this IOMMU supports.
|
||||||
|
*
|
||||||
|
* @iommu_mr: the memory region
|
||||||
|
*/
|
||||||
|
int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* memory_region_name: get a memory region's name
|
* memory_region_name: get a memory region's name
|
||||||
*
|
*
|
||||||
|
23
memory.c
23
memory.c
@ -1915,6 +1915,29 @@ int memory_region_iommu_get_attr(IOMMUMemoryRegion *iommu_mr,
|
|||||||
return imrc->get_attr(iommu_mr, attr, data);
|
return imrc->get_attr(iommu_mr, attr, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int memory_region_iommu_attrs_to_index(IOMMUMemoryRegion *iommu_mr,
|
||||||
|
MemTxAttrs attrs)
|
||||||
|
{
|
||||||
|
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
|
||||||
|
|
||||||
|
if (!imrc->attrs_to_index) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return imrc->attrs_to_index(iommu_mr, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int memory_region_iommu_num_indexes(IOMMUMemoryRegion *iommu_mr)
|
||||||
|
{
|
||||||
|
IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_GET_CLASS(iommu_mr);
|
||||||
|
|
||||||
|
if (!imrc->num_indexes) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return imrc->num_indexes(iommu_mr);
|
||||||
|
}
|
||||||
|
|
||||||
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
|
void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client)
|
||||||
{
|
{
|
||||||
uint8_t mask = 1 << client;
|
uint8_t mask = 1 << client;
|
||||||
|
Loading…
Reference in New Issue
Block a user