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)