aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/iomap_32.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-03-11 10:49:34 +0100
committerIngo Molnar <mingo@elte.hu>2009-03-11 10:49:34 +0100
commitd95c3578120e5bc4784069439f00ccb1b5f87717 (patch)
treec819de31de3983f3d69f223ede07667ff23bf7da /arch/x86/mm/iomap_32.c
parentba1d755a36f66101aa88ac9ebb54694def6ec38d (diff)
parent78b020d035074fc3aa4d017353bb2c32e2aff56f (diff)
downloadlinux-d95c3578120e5bc4784069439f00ccb1b5f87717.tar.gz
Merge branch 'x86/core' into cpus4096
Diffstat (limited to 'arch/x86/mm/iomap_32.c')
-rw-r--r--arch/x86/mm/iomap_32.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c
index d0151d8ce452..04102d42ff42 100644
--- a/arch/x86/mm/iomap_32.c
+++ b/arch/x86/mm/iomap_32.c
@@ -17,8 +17,20 @@
*/
#include <asm/iomap.h>
+#include <asm/pat.h>
#include <linux/module.h>
+int is_io_mapping_possible(resource_size_t base, unsigned long size)
+{
+#ifndef CONFIG_X86_PAE
+ /* There is no way to map greater than 1 << 32 address without PAE */
+ if (base + size > 0x100000000ULL)
+ return 0;
+#endif
+ return 1;
+}
+EXPORT_SYMBOL_GPL(is_io_mapping_possible);
+
/* Map 'pfn' using fixed map 'type' and protections 'prot'
*/
void *
@@ -29,6 +41,15 @@ iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot)
pagefault_disable();
+ /*
+ * For non-PAT systems, promote PAGE_KERNEL_WC to PAGE_KERNEL_UC_MINUS.
+ * PAGE_KERNEL_WC maps to PWT, which translates to uncached if the
+ * MTRR is UC or WC. UC_MINUS gets the real intention, of the
+ * user, which is "WC if the MTRR is WC, UC if you can't do that."
+ */
+ if (!pat_enabled && pgprot_val(prot) == pgprot_val(PAGE_KERNEL_WC))
+ prot = PAGE_KERNEL_UC_MINUS;
+
idx = type + KM_TYPE_NR*smp_processor_id();
vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
set_pte(kmap_pte-idx, pfn_pte(pfn, prot));