aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_memory.c')
-rw-r--r--drivers/gpu/drm/drm_memory.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index 40c4349cb939..fbea69d6f909 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -1,4 +1,4 @@
-/**
+/*
* \file drm_memory.c
* Memory management wrappers for DRM
*
@@ -33,9 +33,16 @@
* OTHER DEALINGS IN THE SOFTWARE.
*/
-#include <linux/highmem.h>
#include <linux/export.h>
-#include <drm/drmP.h>
+#include <linux/highmem.h>
+#include <linux/pci.h>
+#include <linux/vmalloc.h>
+#include <xen/xen.h>
+
+#include <drm/drm_agpsupport.h>
+#include <drm/drm_cache.h>
+#include <drm/drm_device.h>
+
#include "drm_legacy.h"
#if IS_ENABLED(CONFIG_AGP)
@@ -150,15 +157,34 @@ void drm_legacy_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
}
EXPORT_SYMBOL(drm_legacy_ioremapfree);
-u64 drm_get_max_iomem(void)
+bool drm_need_swiotlb(int dma_bits)
{
struct resource *tmp;
resource_size_t max_iomem = 0;
+ /*
+ * Xen paravirtual hosts require swiotlb regardless of requested dma
+ * transfer size.
+ *
+ * NOTE: Really, what it requires is use of the dma_alloc_coherent
+ * allocator used in ttm_dma_populate() instead of
+ * ttm_populate_and_map_pages(), which bounce buffers so much in
+ * Xen it leads to swiotlb buffer exhaustion.
+ */
+ if (xen_pv_domain())
+ return true;
+
+ /*
+ * Enforce dma_alloc_coherent when memory encryption is active as well
+ * for the same reasons as for Xen paravirtual hosts.
+ */
+ if (mem_encrypt_active())
+ return true;
+
for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
max_iomem = max(max_iomem, tmp->end);
}
- return max_iomem;
+ return max_iomem > ((u64)1 << dma_bits);
}
-EXPORT_SYMBOL(drm_get_max_iomem);
+EXPORT_SYMBOL(drm_need_swiotlb);