From 8ef838e5ff7b3c005d7fbc725e17bcccd0e1e1eb Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 28 Feb 2008 13:47:15 +0100 Subject: Add a compat kmap_atomic_prot_pfn to do quick kernel map / unmaps of PCI- or high memory. This is substantially more efficient than drm_bo_kmap, since the mapping only lives on a single processor. Unmapping is done use kunmap_atomic(). Flushes only a single tlb() entry. Add a support utility int drm_bo_pfn_prot() that returns the pfn and desired page protection for a given bo offset. This is all intended for relocations in bound TTMS or vram. Mapping-accessing-unmapping must be atomic, either using preempt_xx() macros or a spinlock. --- linux-core/drm_compat.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'linux-core/drm_compat.c') diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index a745a7d9..32e43a0a 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -729,3 +729,35 @@ void *idr_replace(struct idr *idp, void *ptr, int id) } EXPORT_SYMBOL(idr_replace); #endif + +#if defined(CONFIG_X86) + +#define drm_kmap_get_fixmap_pte(vaddr) \ + pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) + +void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, + pgprot_t protection) +{ + enum fixed_addresses idx; + unsigned long vaddr; + static pte_t *km_pte; + static int initialized = 0; + + if (unlikely(!initialized)) { + km_pte = drm_kmap_get_fixmap_pte(__fix_to_virt(FIX_KMAP_BEGIN)); + initialized = 1; + } + + pagefault_disable(); + idx = type + KM_TYPE_NR*smp_processor_id(); + vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); + set_pte(km_pte-idx, pfn_pte(pfn, protection)); + + return (void*) vaddr; +} + +EXPORT_SYMBOL(kmap_atomic_prot_pfn); + +#endif + + -- cgit v1.2.3 From 1d068973d5f5e6d8d14b4c0c6e28588107aafc6f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 29 Feb 2008 13:31:14 +0100 Subject: Fix compilation breakage on x86-64. --- linux-core/drm_compat.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'linux-core/drm_compat.c') diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index 32e43a0a..eb6c5d81 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -730,8 +730,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) EXPORT_SYMBOL(idr_replace); #endif -#if defined(CONFIG_X86) - +#if defined(DRM_KMAP_ATOMIC_PROT_PFN) #define drm_kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) -- cgit v1.2.3 From 09999c90ab1bf3f7d8b277895c962c8a7b3afc18 Mon Sep 17 00:00:00 2001 From: Patrice Mandin Date: Fri, 29 Feb 2008 21:57:40 +0100 Subject: FIX_KMAP_BEGIN requires CONFIG_HIMEM (see include/asm-i386.h/fixmap.h) --- linux-core/drm_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/drm_compat.c') diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index eb6c5d81..d4044cbd 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -730,7 +730,7 @@ void *idr_replace(struct idr *idp, void *ptr, int id) EXPORT_SYMBOL(idr_replace); #endif -#if defined(DRM_KMAP_ATOMIC_PROT_PFN) +#if defined(DRM_KMAP_ATOMIC_PROT_PFN) && defined(CONFIG_HIMEM) #define drm_kmap_get_fixmap_pte(vaddr) \ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), vaddr), (vaddr)), (vaddr)) -- cgit v1.2.3 From f78cdac8e512642db1aaf09bf9178e23ede25586 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Wed, 5 Mar 2008 15:28:59 +1000 Subject: fixup previous merge --- linux-core/drm_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'linux-core/drm_compat.c') diff --git a/linux-core/drm_compat.c b/linux-core/drm_compat.c index b7b8e395..9b982662 100644 --- a/linux-core/drm_compat.c +++ b/linux-core/drm_compat.c @@ -806,5 +806,5 @@ void *kmap_atomic_prot_pfn(unsigned long pfn, enum km_type type, } EXPORT_SYMBOL(kmap_atomic_prot_pfn); - +#endif -- cgit v1.2.3