--- v5
+++ v1
@@ -1,50 +1,65 @@
From: Tianyu Lan <Tianyu.Lan@microsoft.com>
-Hyper-V provides Isolation VM which has memory encrypt support. Add
-hyperv_cc_platform_has() and return true for check of GUEST_MEM_ENCRYPT
-attribute.
+Hyper-V netvsc driver needs to allocate noncontiguous DMA memory and
+remap it into unencrypted address space before sharing with host. Add
+vmap/vunmap_noncontiguous() callback and handle the remap in the Hyper-V
+dma ops callback.
Signed-off-by: Tianyu Lan <Tianyu.Lan@microsoft.com>
---
-Change since v3:
- * Change code style of checking GUEST_MEM attribute in the
- hyperv_cc_platform_has().
----
- arch/x86/kernel/cc_platform.c | 12 ++++++++++++
- 1 file changed, 12 insertions(+)
+ include/linux/dma-map-ops.h | 3 +++
+ kernel/dma/mapping.c | 18 ++++++++++++++----
+ 2 files changed, 17 insertions(+), 4 deletions(-)
-diff --git a/arch/x86/kernel/cc_platform.c b/arch/x86/kernel/cc_platform.c
-index 03bb2f343ddb..7b66793c0f25 100644
---- a/arch/x86/kernel/cc_platform.c
-+++ b/arch/x86/kernel/cc_platform.c
-@@ -11,6 +11,7 @@
- #include <linux/cc_platform.h>
- #include <linux/mem_encrypt.h>
+diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
+index 0d5b06b3a4a6..f7b9958ca20a 100644
+--- a/include/linux/dma-map-ops.h
++++ b/include/linux/dma-map-ops.h
+@@ -27,6 +27,9 @@ struct dma_map_ops {
+ unsigned long attrs);
+ void (*free_noncontiguous)(struct device *dev, size_t size,
+ struct sg_table *sgt, enum dma_data_direction dir);
++ void *(*vmap_noncontiguous)(struct device *dev, size_t size,
++ struct sg_table *sgt);
++ void (*vunmap_noncontiguous)(struct device *dev, void *addr);
+ int (*mmap)(struct device *, struct vm_area_struct *,
+ void *, dma_addr_t, size_t, unsigned long attrs);
-+#include <asm/mshyperv.h>
- #include <asm/processor.h>
+diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
+index 9478eccd1c8e..7fd751d866cc 100644
+--- a/kernel/dma/mapping.c
++++ b/kernel/dma/mapping.c
+@@ -674,8 +674,14 @@ void *dma_vmap_noncontiguous(struct device *dev, size_t size,
+ const struct dma_map_ops *ops = get_dma_ops(dev);
+ unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
- static bool __maybe_unused intel_cc_platform_has(enum cc_attr attr)
-@@ -58,9 +59,20 @@ static bool amd_cc_platform_has(enum cc_attr attr)
- #endif
+- if (ops && ops->alloc_noncontiguous)
+- return vmap(sgt_handle(sgt)->pages, count, VM_MAP, PAGE_KERNEL);
++ if (ops) {
++ if (ops->vmap_noncontiguous)
++ return ops->vmap_noncontiguous(dev, size, sgt);
++ else if (ops->alloc_noncontiguous)
++ return vmap(sgt_handle(sgt)->pages, count, VM_MAP,
++ PAGE_KERNEL);
++ }
++
+ return page_address(sg_page(sgt->sgl));
}
+ EXPORT_SYMBOL_GPL(dma_vmap_noncontiguous);
+@@ -684,8 +690,12 @@ void dma_vunmap_noncontiguous(struct device *dev, void *vaddr)
+ {
+ const struct dma_map_ops *ops = get_dma_ops(dev);
-+static bool hyperv_cc_platform_has(enum cc_attr attr)
-+{
-+#if IS_ENABLED(CONFIG_HYPERV)
-+ return attr == CC_ATTR_GUEST_MEM_ENCRYPT;
-+#else
-+ return false;
-+#endif
-+}
-
- bool cc_platform_has(enum cc_attr attr)
- {
-+ if (hv_is_isolation_supported())
-+ return hyperv_cc_platform_has(attr);
-+
- if (sme_me_mask)
- return amd_cc_platform_has(attr);
+- if (ops && ops->alloc_noncontiguous)
+- vunmap(vaddr);
++ if (ops) {
++ if (ops->vunmap_noncontiguous)
++ ops->vunmap_noncontiguous(dev, vaddr);
++ else if (ops->alloc_noncontiguous)
++ vunmap(vaddr);
++ }
+ }
+ EXPORT_SYMBOL_GPL(dma_vunmap_noncontiguous);
--
2.25.1