enabling graphics memory dma remapping
Subsystems (2)
cover enabling graphics memory dma remapping
Intel IOMMU (a.k.a VT-d) is under rapid deployment on desktop and mobile platforms. As platform provides multiple dma remap engines for devices like those lives on south bridge (net, sound, etc.), and we also have one engine specific to graphics device.
If this engine is functioning, the access to graphics memory routine is to first look up in GART table, which return virtual dma address that will further be route to graphics DMAR engine, which then looking up DMAR table to get real physical address.
Current intel iommu function in kernel is providing a graphics workaround kernel config (CONFIG_DMAR_GFX_WA) to make a 1:1 mapping initialization for graphics device, so what we fill in GART table got from agpgart page alloc is identical to virtual dma address in DMAR table. No change needs to be made for graphics driver.
Following patches try to add dma remapping function to agpgart module, so we won't depend on intel iommu graphics workaround. As DMAR is only available on x86_64 now, so these patches can only work for x86_64 system.
Here're three patches below:
- intel_iommu-explicit-export-current-graphics-dmar-status.patch
This exports current status of graphics dma remap engine, which depends on current platform iommu support, kernel config or runtime config. This info will be used in agp module for detect whether we should do remapping or not.
- AGP-Add-generic-support-for-graphics-dma-remapping.patch
This adds new hooks into agp bridge driver to do map/unmap when bind/unbind memory into GART table. The aim is to provide generic interfaces to let driver implement hardware specific operations.
- AGP-intel_agp-add-support-for-graphics-dma-remapping.patch
This implements graphics dma remapping support in intel_agp module, current only desktop chipset G33 series can use it.
Thanks.
RFC PATCH 1/4 explicit export current graphics dmar status
[PATCH] [intel_iommu] explicit export current graphics dmar status
To make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Also this one trys to make dmar_disabled really present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.
--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)
drivers/pci/intel-iommu.c +16 -2
@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;
@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ; + }if (early_dmar_detect ()) { iommu_detected =1 ; }
include/linux/dmar.h +6 -0
@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;
@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */
Signature · 1 line
1.5.3.5
RFC PATCH 2/4 Add generic support for graphics dma remapping
In reply to Zhenyu Wang[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.
--- 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(-)
drivers/char/agp/agp.h +14 -0
@@ -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;
drivers/char/agp/backend.c +20 -1
@@ -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 ();
drivers/char/agp/generic.c +14 -0
@@ -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);
include/linux/agp_backend.h +7 -0
@@ -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
Signature · 1 line
1.5.3.5
RFC PATCH 3/4 intel_agp: add support for graphics dma remapping on G33
In reply to Zhenyu Wang[PATCH] [AGP] intel_agp: add support for graphics dma remapping on G33
When graphics dma remapping engine is active, we must fill gart table with dma address from dmar engine, as now graphics device access to graphics memory must go through dma remapping table to get real physical address.
Add support on G33 chipset, which has graphics device specific dmar engine avaiable.
--- drivers/char/agp/Kconfig | 12 +++- drivers/char/agp/intel-agp.c | 134 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 5 deletions(-)
drivers/char/agp/Kconfig +10 -2
@@ -74,8 +74,16 @@ config AGP_INTEL on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, 852GM, 855GM, 865G and I915 integrated graphics chipsets. - - + +config AGP_INTEL_DMAR + bool + depends on AGP_INTEL && DMAR && !DMAR_GFX_WA + default y + help + This option will enable graphics address remapping with Intel + DMAR engine aka VT-d if you don't select graphics workaround on + Intel DMAR. The graphics address filled to gart table will be + changed by remapping within graphics DMAR engine for domain. config AGP_NVIDIA tristate "NVIDIA nForce/nForce2 chipset support"
drivers/char/agp/intel-agp.c +131 -3
158 lines not on this page · raw message
Signature · 1 line
1.5.3.5
cover enabling graphics memory dma remapping
In reply to Zhenyu WangQuoted 12 lines · Zhenyu Wang
Here're three patches below:
- intel_iommu-explicit-export-current-graphics-dmar-status.patch
This exports current status of graphics dma remap engine, which depends on current platform iommu support, kernel config or runtime config. This info will be used in agp module for detect whether we should do remapping or not.
- AGP-Add-generic-support-for-graphics-dma-remapping.patch
Quoted 8 lines
This adds new hooks into agp bridge driver to do map/unmap when bind/unbind memory into GART table. The aim is to provide generic interfaces to let driver implement hardware specific operations.
- AGP-intel_agp-add-support-for-graphics-dma-remapping.patch
This implements graphics dma remapping support in
intel_agpmodule, current only desktop chipset G33 series can use it.
Above patch series are against master branch, following threads try to rebase them to Airlie's agp-mm tree for -mm inclusion.
Thanks.
PATCH 1/4 explicit export current graphics dmar status
[agp-mm] [intel_iommu] explicit export current graphics dmar status
To make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Also this one trys to make dmar_disabled really present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.
--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)
drivers/pci/intel-iommu.c +16 -2
@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;
@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ; + }if (early_dmar_detect ()) { iommu_detected =1 ; }
include/linux/dmar.h +6 -0
@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;
@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */
Signature · 1 line
1.5.3.4
Re: [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status
Quoted 88 lines · Zhenyu Wang
[agp-mm] [
intel_iommu] explicit export current graphics dmar statusTo make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Also this one trys to make
dmar_disabledreally present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.Signed-off-by Zhenyu Wang <[email protected]>--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)drivers/pci/intel-iommu.c +16
-2@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ; + }if (early_dmar_detect ()) { iommu_detected =1 ; }include/linux/dmar.h +6
-0@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ Signature · 1 line
1.5.3.4
Any comments to this one? Is it ok to push this iommu patch with agp dma remapping patches to next -mm?
Thanks.
Re: [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status
Sorry for the late reply.
comments below...
Quoted 11 lines · Zhenyu Wang
Quoted 10 lines · Zhenyu Wang
[agp-mm] [
intel_iommu] explicit export current graphics dmar statusTo make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Also this one trys to make
dmar_disabledreally present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.
do you think this exporting will be needed?
If so why and when would someone use it?
Quoted 39 lines
Quoted 39 lines
Signed-off-by Zhenyu Wang <[email protected]>--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)drivers/pci/intel-iommu.c +11
-1@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)
Quoted 8 lines
drivers/pci/intel-iommu.c static void __init iommu_exit_mempool(void) · line 2206
Quoted 8 lines
drivers/pci/intel-iommu.c +4
-1void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ;
Why the bloat? This block of 7 lines looks like it does the same as the 2 you replaced.
Quoted 17 lines
Quoted 17 lines
drivers/pci/intel-iommu.c +1
-0+ }if (early_dmar_detect ()) { iommu_detected =1 ; }include/linux/dmar.h +2
-0@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;
Quoted 8 lines
include/linux/dmar.h static inline int intel_iommu_init(void) · line 89
Quoted 8 lines
include/linux/dmar.h +4
-0@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}
Um this function is silly lets not post it.
Quoted 10 lines
Quoted 6 lines
include/linux/dmar.h +0
-0#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ Signature · 1 line
1.5.3.4Any comments to this one? Is it ok to push this iommu patch with agp dma remapping patches to next -mm?
Its not ready for posting.
--mgross
Re: [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status
Mark, sorry for missing this for long time...
Quoted 7 lines · mark gross
Quoted 7 lines
Quoted 7 lines
[agp-mm] [
intel_iommu] explicit export current graphics dmar statusTo make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Quoted 6 lines
Quoted 3 lines
Quoted 3 lines
Also this one trys to make
dmar_disabledreally present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.do you think this exporting will be needed?
If so why and when would someone use it?
This is used for our graphics driver module to know if we have to do dma remapping in iommu case, both in kernel config and kernel boot time param config.
The simplest case is that DMAR_GFX_WA is on, which no dma mapping will act in intel_agp.
If no DMAR_GFX_WA, we still have boot param to turn off whole intel iommu (intel_iommu=off), just turn off graphics remap engine (intel_iommu=igfx_off). So this exported interface is used to know that in runtime.
Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
Signed-off-by Zhenyu Wang <[email protected]>--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)drivers/pci/intel-iommu.c +11
-1@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)
Quoted 11 lines
Quoted 8 lines
drivers/pci/intel-iommu.c static void __init iommu_exit_mempool(void) · line 2206
Quoted 8 lines
drivers/pci/intel-iommu.c +4
-1void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ;Why the bloat? This block of 7 lines looks like it does the same as the 2 you replaced.
No, dmar_disabled is not set in origin, which can't tell if it's turned off with (intel_iommu=off) later.
Quoted 43 lines
Quoted 18 lines
Quoted 18 lines
drivers/pci/intel-iommu.c +1
-0+ }if (early_dmar_detect ()) { iommu_detected =1 ; }include/linux/dmar.h +2
-0@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;Quoted 8 lines
include/linux/dmar.h static inline int intel_iommu_init(void) · line 89
Quoted 8 lines
include/linux/dmar.h +4
-0@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}Um this function is silly lets not post it.
Quoted 10 lines
Quoted 6 lines
include/linux/dmar.h +0
-0#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ Signature · 1 line
1.5.3.4Any comments to this one? Is it ok to push this iommu patch with agp dma remapping patches to next -mm?
Its not ready for posting.
--mgross
Re: [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status
Quoted 15 lines · Zhenyu Wang
Mark, sorry for missing this for long time...
Quoted 11 lines · mark gross
Quoted 10 lines
Quoted 10 lines
[agp-mm] [
intel_iommu] explicit export current graphics dmar statusTo make it possbile to tell other modules about curent graphics dmar engine status, that could decide if graphics driver should remap physical address to dma address.
Also this one trys to make
dmar_disabledreally present current status of DMAR, which would be used for completely express graphics dmar engine is active or not.
Quoted 6 lines
Quoted 2 lines
do you think this exporting will be needed?
If so why and when would someone use it?This is used for our graphics driver module to know if we have to do dma remapping in iommu case, both in kernel config and kernel boot time param config.
ok. How soon do you need this export?
Quoted 61 lines
The simplest case is that
DMAR_GFX_WAis on, which no dma mapping will act inintel_agp.If no
DMAR_GFX_WA, we still have boot param to turn off whole intel iommu (intel_iommu=off), just turn off graphics remap engine (intel_iommu=igfx_off). So this exported interface is used to know that in runtime.Quoted 40 lines
Quoted 40 lines
Quoted 40 lines
Signed-off-by Zhenyu Wang <[email protected]>--- drivers/pci/intel-iommu.c | 18 ++++++++++++++++-- include/linux/dmar.h | 6 ++++++ 2 files changed, 22 insertions(+), 2 deletions(-)drivers/pci/intel-iommu.c +11
-1@@ -53,7 +53,7 @@static void domain_remove_dev_info (struct dmar_domain *domain);static int dmar_disabled; -static int __initdata dmar_map_gfx =1 ; +static int dmar_map_gfx =1 ;static int dmar_forcedac;#define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))@@ -86,6 +86,16 @@ static int __init intel_iommu_setup(char *str) }__setup ("intel_iommu=" , intel_iommu_setup); +int intel_iommu_gfx_remapping (void ) +{ +#ifndef CONFIG_DMAR_GFX_WA +if (!dmar_disabled && iommu_detected && dmar_map_gfx) +return 1 ; +#endif +return 0 ; +} +EXPORT_SYMBOL_GPL (intel_iommu_gfx_remapping); +static struct kmem_cache *iommu_domain_cache;static struct kmem_cache *iommu_devinfo_cache;static struct kmem_cache *iommu_iova_cache;@@ -2189,8 +2199,12 @@ static void __init iommu_exit_mempool(void)Quoted 11 lines
Quoted 8 lines
drivers/pci/intel-iommu.c static void __init iommu_exit_mempool(void) · line 2206
Quoted 8 lines
drivers/pci/intel-iommu.c +4
-1void __init detect_intel_iommu (void ) { -if (swiotlb || no_iommu || iommu_detected || dmar_disabled) +if (dmar_disabled) +return ; +if (swiotlb || no_iommu || iommu_detected) { + dmar_disabled =1 ;return ;Why the bloat? This block of 7 lines looks like it does the same as the 2 you replaced.
Quoted 3 lines
No,
dmar_disabledis not set in origin, which can't tell if it's turned off with (intel_iommu=off) later.
oops, I missed that how about something like
if (swiotlb || no_iommu || iommu_detected || dmar_disabled) {
dmar_disabled = 1;
return;
}I guess your way is ok too.
Quoted 36 lines
Quoted 36 lines
Quoted 18 lines
Quoted 18 lines
drivers/pci/intel-iommu.c +1
-0+ }if (early_dmar_detect ()) { iommu_detected =1 ; }include/linux/dmar.h +2
-0@@ -47,6 +47,8 @@ extern int intel_iommu_init(void);extern int dmar_table_init (void );extern int early_dmar_detect (void ); +extern int intel_iommu_gfx_remapping (void ); +extern struct list_head dmar_drhd_units;extern struct list_head dmar_rmrr_units;Quoted 8 lines
include/linux/dmar.h static inline int intel_iommu_init(void) · line 89
Quoted 8 lines
include/linux/dmar.h +4
-0@@ -81,6 +83,10 @@ static inline int intel_iommu_init(void) {return -ENODEV ; } +static inline int intel_iommu_gfx_remapping (void ) +{ +return 0 ; +}Um this function is silly lets not post it.
Quoted 7 lines
Quoted 6 lines
include/linux/dmar.h +0
-0#endif /* !CONFIG_DMAR */ #endif /* __DMAR_H__ */ Signature · 1 line
1.5.3.4
Quoted 5 lines
Quoted 5 lines
Quoted 3 lines
Any comments to this one? Is it ok to push this iommu patch with agp dma remapping patches to next -mm?
Its not ready for posting.
send me your current patch and eta for the graphics module patches so I can better coordinate with you.
--mgross
Re: [agp-mm][PATCH 1/4][intel_iommu] explicit export current graphics dmar status
Quoted 6 lines · mark gross
Quoted 3 lines
This is used for our graphics driver module to know if we have to do dma remapping in iommu case, both in kernel config and kernel boot time param config.
ok. How soon do you need this export?
As graphics part of these patches depend on this one, it should go first, or along with agpgart patches, that should first be in Airlie's agp-mm queue.
Quoted 2 lines
send me your current patch and eta for the graphics module patches so I can better coordinate with you.
You can find my current patches against agp-mm tree (so equally against current -mm kernel) here, http://people.freedesktop.org/~zhen/, fixed with some warnings from checkpatch.
PATCH 2/4 Add generic support for graphics dma remapping
In reply to Zhenyu Wang[agp-mm] [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.
--- drivers/char/agp/agp.h | 13 +++++++++++++ drivers/char/agp/backend.c | 21 ++++++++++++++++++++- drivers/char/agp/generic.c | 14 ++++++++++++++ include/linux/agp_backend.h | 7 +++++++ 4 files changed, 54 insertions(+), 1 deletions(-)
drivers/char/agp/agp.h +13 -0
@@ -119,6 +119,17 @@ struct agp_bridge_driver {void (*agp_destroy_page)(void *,int flags);int (*agp_type_to_mask_type) (struct agp_bridge_data *,int );void (*chipset_flush)(struct agp_bridge_data *); +/* 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 {
@@ -133,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;
drivers/char/agp/backend.c +20 -1
@@ -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 ();
drivers/char/agp/generic.c +14 -0
@@ -422,6 +422,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 )
@@ -461,6 +469,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);
include/linux/agp_backend.h +7 -0
@@ -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
Signature · 1 line
1.5.3.4
PATCH 3/4 intel_agp: add support for graphics dma remapping on G33
In reply to Zhenyu Wang[agp-mm] [AGP] intel_agp: add support for graphics dma remapping on G33
When graphics dma remapping engine is active, we must fill gart table with dma address from dmar engine, as now graphics device access to graphics memory must go through dma remapping table to get real physical address.
Add support on G33 chipset, which has graphics device specific dmar engine avaiable.
--- drivers/char/agp/Kconfig | 12 +++- drivers/char/agp/intel-agp.c | 134 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 5 deletions(-)
drivers/char/agp/Kconfig +10 -2
@@ -74,8 +74,16 @@ config AGP_INTEL on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875, E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G, 852GM, 855GM, 865G and I915 integrated graphics chipsets. - - + +config AGP_INTEL_DMAR + bool + depends on AGP_INTEL && DMAR && !DMAR_GFX_WA + default y + help + This option will enable graphics address remapping with Intel + DMAR engine aka VT-d if you don't select graphics workaround on + Intel DMAR. The graphics address filled to gart table will be + changed by remapping within graphics DMAR engine for domain. config AGP_NVIDIA tristate "NVIDIA nForce/nForce2 chipset support"
drivers/char/agp/intel-agp.c +131 -3
158 lines not on this page · raw message
Signature · 1 line
1.5.3.4