Module Name:    src
Committed By:   riastradh
Date:           Mon Aug 27 15:32:39 UTC 2018

Modified Files:
        src/sys/external/bsd/drm2/dist/drm: drm_prime.c
        src/sys/external/bsd/drm2/dist/drm/ttm: ttm_bo.c
        src/sys/external/bsd/drm2/dist/include/drm: drmP.h
        src/sys/external/bsd/drm2/include/drm: bus_dma_hacks.h

Log Message:
Check for DMA-safe addresses before allowing DRM prime import.


To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/external/bsd/drm2/dist/drm/drm_prime.c
cvs rdiff -u -r1.13 -r1.14 src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c
cvs rdiff -u -r1.31 -r1.32 src/sys/external/bsd/drm2/dist/include/drm/drmP.h
cvs rdiff -u -r1.16 -r1.17 \
    src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/external/bsd/drm2/dist/drm/drm_prime.c
diff -u src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.6 src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.7
--- src/sys/external/bsd/drm2/dist/drm/drm_prime.c:1.6	Mon Aug 27 15:29:31 2018
+++ src/sys/external/bsd/drm2/dist/drm/drm_prime.c	Mon Aug 27 15:32:39 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drm_prime.c,v 1.6 2018/08/27 15:29:31 riastradh Exp $	*/
+/*	$NetBSD: drm_prime.c,v 1.7 2018/08/27 15:32:39 riastradh Exp $	*/
 
 /*
  * Copyright © 2012 Red Hat
@@ -29,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.6 2018/08/27 15:29:31 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: drm_prime.c,v 1.7 2018/08/27 15:32:39 riastradh Exp $");
 
 #include <linux/export.h>
 #include <linux/dma-buf.h>
@@ -928,6 +928,18 @@ out1:	kfree(segs);
 out0:	return ret;
 }
 
+bool
+drm_prime_sg_importable(bus_dma_tag_t dmat, struct sg_table *sgt)
+{
+	unsigned i;
+
+	for (i = 0; i < sgt->sgt_npgs; i++) {
+		if (bus_dmatag_bounces_paddr(dmat, sgt->sgt_pgs[i]))
+			return false;
+	}
+	return true;
+}
+
 #else  /* !__NetBSD__ */
 
 /**

Index: src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c
diff -u src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c:1.13 src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c:1.14
--- src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c:1.13	Mon Aug 27 07:53:16 2018
+++ src/sys/external/bsd/drm2/dist/drm/ttm/ttm_bo.c	Mon Aug 27 15:32:39 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ttm_bo.c,v 1.13 2018/08/27 07:53:16 riastradh Exp $	*/
+/*	$NetBSD: ttm_bo.c,v 1.14 2018/08/27 15:32:39 riastradh Exp $	*/
 
 /**************************************************************************
  *
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ttm_bo.c,v 1.13 2018/08/27 07:53:16 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ttm_bo.c,v 1.14 2018/08/27 15:32:39 riastradh Exp $");
 
 #define pr_fmt(fmt) "[TTM] " fmt
 
@@ -41,6 +41,7 @@ __KERNEL_RCSID(0, "$NetBSD: ttm_bo.c,v 1
 #include <uvm/uvm_object.h>
 #endif
 
+#include <drm/drmP.h>
 #include <drm/ttm/ttm_module.h>
 #include <drm/ttm/ttm_bo_driver.h>
 #include <drm/ttm/ttm_placement.h>
@@ -1140,6 +1141,11 @@ int ttm_bo_init(struct ttm_bo_device *bd
 	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
 	bool locked;
 
+	if (sg && !drm_prime_sg_importable(bdev->dmat, sg)) {
+		pr_err("DRM prime buffer violates DMA constraints\n");
+		return -EIO;
+	}
+
 	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
 	if (ret) {
 		pr_err("Out of kernel memory\n");

Index: src/sys/external/bsd/drm2/dist/include/drm/drmP.h
diff -u src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.31 src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.32
--- src/sys/external/bsd/drm2/dist/include/drm/drmP.h:1.31	Mon Aug 27 15:32:06 2018
+++ src/sys/external/bsd/drm2/dist/include/drm/drmP.h	Mon Aug 27 15:32:39 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: drmP.h,v 1.31 2018/08/27 15:32:06 riastradh Exp $	*/
+/*	$NetBSD: drmP.h,v 1.32 2018/08/27 15:32:39 riastradh Exp $	*/
 
 /*
  * Internal Header for the Direct Rendering Manager
@@ -1189,6 +1189,7 @@ extern int drm_prime_sg_to_bus_dmamem(bu
 extern int drm_prime_bus_dmamap_load_sgt(bus_dma_tag_t, bus_dmamap_t, struct sg_table *);
 extern bus_size_t drm_prime_sg_size(struct sg_table *);
 extern void drm_prime_sg_free(struct sg_table *);
+extern bool drm_prime_sg_importable(bus_dma_tag_t, struct sg_table *);
 #else
 extern int drm_prime_sg_to_page_addr_arrays(struct sg_table *sgt, struct page **pages,
 					    dma_addr_t *addrs, int max_pages);

Index: src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h
diff -u src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.16 src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.17
--- src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h:1.16	Mon Aug 27 15:32:20 2018
+++ src/sys/external/bsd/drm2/include/drm/bus_dma_hacks.h	Mon Aug 27 15:32:39 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus_dma_hacks.h,v 1.16 2018/08/27 15:32:20 riastradh Exp $	*/
+/*	$NetBSD: bus_dma_hacks.h,v 1.17 2018/08/27 15:32:39 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -91,6 +91,27 @@ bus_dmamem_pgfl(bus_dma_tag_t tag)
 #endif
 }
 
+static inline bool
+bus_dmatag_bounces_paddr(bus_dma_tag_t dmat, paddr_t pa)
+{
+#if defined(__i386__) || defined(__x86_64__)
+	return pa < dmat->_bounce_alloc_lo || dmat->_bounce_alloc_hi <= pa;
+#elif defined(__arm__) || defined(__aarch64__)
+	unsigned i;
+
+	for (i = 0; i < dmat->_nranges; i++) {
+		const struct arm32_dma_range *dr = &dmat->_ranges[i];
+		if (dr->dr_sysbase <= pa && pa - dr->dr_sysbase <= dr->dr_len)
+			return false;
+	}
+	return true;
+#elif defined(__powerpc__)
+	return dmat->_bounce_thresh && pa >= dmat->_bounce_thresh;
+#elif defined(__sparc__) || defined(__sparc64__)
+	return false;		/* no bounce buffers ever */
+#endif
+}
+
 static inline int
 bus_dmamap_load_pglist(bus_dma_tag_t tag, bus_dmamap_t map,
     struct pglist *pglist, bus_size_t size, int flags)

Reply via email to