lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20071218051139.GC12564@zhen-devel.sh.intel.com>
Date:	Tue, 18 Dec 2007 13:11:39 +0800
From:	Zhenyu Wang <zhenyu.z.wang@...el.com>
To:	Dave Airlie <airlied@...ux.ie>
Cc:	LKML <linux-kernel@...r.kernel.org>,
	Keith Packard <keithp@...thp.com>,
	Eric Anholt <eric@...olt.net>,
	"Gross, Mark" <mark.gross@...el.com>
Subject: [RFC][PATCH 2/4][AGP] Add generic support for graphics dma remapping


[PATCH] [AGP] Add generic support for graphics dma remapping

New driver hooks for support graphics memory dma remapping
are introduced in this patch. It makes generic code can
tell if current device needs dma remapping, then call driver
provided interfaces for mapping and unmapping. Change has
also been made to handle scratch_page in remapping case.

Signed-off-by: Zhenyu Wang <zhenyu.z.wang@...el.com>
---
 drivers/char/agp/agp.h      |   14 ++++++++++++++
 drivers/char/agp/backend.c  |   21 ++++++++++++++++++++-
 drivers/char/agp/generic.c  |   14 ++++++++++++++
 include/linux/agp_backend.h |    7 +++++++
 4 files changed, 55 insertions(+), 1 deletions(-)

diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index b83824c..7806da1 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -118,6 +118,18 @@ struct agp_bridge_driver {
 	void *(*agp_alloc_page)(struct agp_bridge_data *);
 	void (*agp_destroy_page)(void *, int flags);
         int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
+
+	/* Tell current graphics dma remapping engine status, there might
+	 * be driver or platform specific way to detect. */
+	int (*agp_require_remapping)(void);
+
+	/* This can support single page remapping via void *virt for like
+	 * scratch_page, or normal bunch of mem page range via struct
+	 * agp_memory *mem.
+	 */
+	int (*agp_map_page)(struct agp_memory *mem, void *virt, dma_addr_t *ret, int is_single);
+
+	void (*agp_unmap_page)(struct agp_memory *mem, dma_addr_t ret, int is_single);
 };
 
 struct agp_bridge_data {
@@ -132,6 +144,8 @@ struct agp_bridge_data {
 	u32 *gatt_table_real;
 	unsigned long scratch_page;
 	unsigned long scratch_page_real;
+	dma_addr_t scratch_page_dma;
+	u8 scratch_page_is_mapped;
 	unsigned long gart_bus_addr;
 	unsigned long gatt_bus_addr;
 	u32 mode;
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 832ded2..cc6d648 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -151,7 +151,20 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 
 		bridge->scratch_page_real = virt_to_gart(addr);
 		bridge->scratch_page =
-		    bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
+			bridge->driver->mask_memory(bridge, bridge->scratch_page_real, 0);
+
+		if (bridge->driver->agp_require_remapping &&
+				bridge->driver->agp_require_remapping()) {
+			if (bridge->driver->agp_map_page(NULL, addr, &bridge->scratch_page_dma, 1)) {
+				printk(KERN_ERR PFX "unable to map scratch page\n");
+				rc = -ENOMEM;
+				goto err_out;
+			}
+			bridge->scratch_page_is_mapped = TRUE;
+			bridge->scratch_page =
+				bridge->driver->mask_memory(bridge,
+						bridge->scratch_page_dma, 0);
+		}
 	}
 
 	size_value = bridge->driver->fetch_size();
@@ -189,6 +202,9 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
 
 err_out:
 	if (bridge->driver->needs_scratch_page) {
+		if (bridge->scratch_page_is_mapped)
+			bridge->driver->agp_unmap_page(NULL, bridge->scratch_page_dma, 1);
+
 		bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real),
 						 AGP_PAGE_DESTROY_UNMAP);
 		flush_agp_mappings();
@@ -217,6 +233,9 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
 
 	if (bridge->driver->agp_destroy_page &&
 	    bridge->driver->needs_scratch_page) {
+		if (bridge->scratch_page_is_mapped)
+			bridge->driver->agp_unmap_page(NULL, bridge->scratch_page_dma, 1);
+
 		bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real),
 						 AGP_PAGE_DESTROY_UNMAP);
 		flush_agp_mappings();
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 64b2f6d..8966c94 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -415,6 +415,14 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
 		curr->bridge->driver->cache_flush();
 		curr->is_flushed = TRUE;
 	}
+
+	if (curr->bridge->driver->agp_require_remapping &&
+			curr->bridge->driver->agp_require_remapping()) {
+		ret_val = curr->bridge->driver->agp_map_page(curr, NULL, NULL, 0);
+		if (ret_val)
+			return ret_val;
+	}
+
 	ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
 
 	if (ret_val != 0)
@@ -454,6 +462,12 @@ int agp_unbind_memory(struct agp_memory *curr)
 
 	curr->is_bound = FALSE;
 	curr->pg_start = 0;
+
+	if (curr->is_mapped) {
+		if (curr->bridge->driver->agp_unmap_page)
+			curr->bridge->driver->agp_unmap_page(curr, 0, 0);
+		curr->is_mapped = FALSE;
+	}
 	return 0;
 }
 EXPORT_SYMBOL(agp_unbind_memory);
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index abc521c..5b7c431 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -87,7 +87,14 @@ struct agp_memory {
 	u32 physical;
 	u8 is_bound;
 	u8 is_flushed;
+	u8 is_mapped;
         u8 vmalloc_flag;
+	/* Following are used in graphics dma remapping case,
+	 * for map/unmap via sg interfaces.
+	 */
+	struct scatterlist *sg_list;
+	int num_sg;
+	u8 sg_vmalloc_flag;
 };
 
 #define AGP_NORMAL_MEMORY 0
-- 
1.5.3.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ