@@ -76,6 +76,20 @@
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
+enum dma_memory_types {
+ /* Normal memory without any extra properties like P2P, e.t.c */
+ DMA_MEMORY_TYPE_NORMAL,
+ /* Memory which is p2p capable */
+ DMA_MEMORY_TYPE_P2P,
+ /* Encrypted memory (TDX) */
+ DMA_MEMORY_TYPE_ENCRYPTED,
+};
+
+struct dma_memory_type {
+ enum dma_memory_types type;
+ struct dev_pagemap *p2p_pgmap;
+};
+
#ifdef CONFIG_DMA_API_DEBUG
void debug_dma_mapping_error(struct device *dev, dma_addr_t dma_addr);
void debug_dma_map_single(struct device *dev, const void *addr,
@@ -149,6 +163,8 @@ void *dma_vmap_noncontiguous(struct device *dev, size_t size,
void dma_vunmap_noncontiguous(struct device *dev, void *vaddr);
int dma_mmap_noncontiguous(struct device *dev, struct vm_area_struct *vma,
size_t size, struct sg_table *sgt);
+
+void dma_get_memory_type(struct page *page, struct dma_memory_type *type);
#else /* CONFIG_HAS_DMA */
static inline dma_addr_t dma_map_page_attrs(struct device *dev,
struct page *page, size_t offset, size_t size,
@@ -279,6 +295,10 @@ static inline int dma_mmap_noncontiguous(struct device *dev,
{
return -EINVAL;
}
+static inline void dma_get_memory_type(struct page *page,
+ struct dma_memory_type *type)
+{
+}
#endif /* CONFIG_HAS_DMA */
#if defined(CONFIG_HAS_DMA) && defined(CONFIG_DMA_NEED_SYNC)
@@ -6,6 +6,7 @@
* Copyright (c) 2006 Tejun Heo <teheo@suse.de>
*/
#include <linux/memblock.h> /* for max_pfn */
+#include <linux/memremap.h>
#include <linux/acpi.h>
#include <linux/dma-map-ops.h>
#include <linux/export.h>
@@ -14,6 +15,7 @@
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
+#include <linux/cc_platform.h>
#include "debug.h"
#include "direct.h"
@@ -894,3 +896,31 @@ unsigned long dma_get_merge_boundary(struct device *dev)
return ops->get_merge_boundary(dev);
}
EXPORT_SYMBOL_GPL(dma_get_merge_boundary);
+
+/**
+ * dma_get_memory_type - get the DMA memory type of the page supplied
+ * @page: page to check
+ * @type: memory type of that page
+ *
+ * Return the DMA memory type for the struct page. Pages with the same
+ * memory type can be combined into the same IOVA mapping. Users of the
+ * dma_iova family of functions must seperate the memory they want to map
+ * into same-memory type ranges.
+ */
+void dma_get_memory_type(struct page *page, struct dma_memory_type *type)
+{
+ /* TODO: Rewrite this check to rely on specific struct page flags */
+ if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
+ type->type = DMA_MEMORY_TYPE_ENCRYPTED;
+ return;
+ }
+
+ if (is_pci_p2pdma_page(page)) {
+ type->type = DMA_MEMORY_TYPE_P2P;
+ type->p2p_pgmap = page->pgmap;
+ return;
+ }
+
+ type->type = DMA_MEMORY_TYPE_NORMAL;
+}
+EXPORT_SYMBOL_GPL(dma_get_memory_type);