diff options
author | Keith Packard <keithp@keithp.com> | 2008-10-30 22:37:09 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-31 05:12:38 -0400 |
commit | fd9409343521eac22b6ed51686128a643c7c976b (patch) | |
tree | d70e3f009a29a7bbfe68b956608854db416bc2af /arch/x86/mm | |
parent | 721d5dfe7e516954c501d5e9d0dfab379cf4241a (diff) |
x86: add iomap_atomic*()/iounmap_atomic() on 32-bit using fixmaps
Impact: introduce new APIs, separate kmap code from CONFIG_HIGHMEM
This takes the code used for CONFIG_HIGHMEM memory mappings except that
it's designed for dynamic IO resource mapping.
These fixmaps are available even with CONFIG_HIGHMEM turned off.
Signed-off-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 3 | ||||
-rw-r--r-- | arch/x86/mm/iomap_32.c | 59 |
3 files changed, 61 insertions, 3 deletions
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 59f89b434b45..fea4565ff576 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ | 1 | obj-y := init_$(BITS).o fault.o ioremap.o extable.o pageattr.o mmap.o \ |
2 | pat.o pgtable.o gup.o | 2 | pat.o pgtable.o gup.o |
3 | 3 | ||
4 | obj-$(CONFIG_X86_32) += pgtable_32.o | 4 | obj-$(CONFIG_X86_32) += pgtable_32.o iomap_32.o |
5 | 5 | ||
6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o | 6 | obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o |
7 | obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o | 7 | obj-$(CONFIG_X86_PTDUMP) += dump_pagetables.o |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 8396868e82c5..c483f4242079 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -334,7 +334,6 @@ int devmem_is_allowed(unsigned long pagenr) | |||
334 | return 0; | 334 | return 0; |
335 | } | 335 | } |
336 | 336 | ||
337 | #ifdef CONFIG_HIGHMEM | ||
338 | pte_t *kmap_pte; | 337 | pte_t *kmap_pte; |
339 | pgprot_t kmap_prot; | 338 | pgprot_t kmap_prot; |
340 | 339 | ||
@@ -357,6 +356,7 @@ static void __init kmap_init(void) | |||
357 | kmap_prot = PAGE_KERNEL; | 356 | kmap_prot = PAGE_KERNEL; |
358 | } | 357 | } |
359 | 358 | ||
359 | #ifdef CONFIG_HIGHMEM | ||
360 | static void __init permanent_kmaps_init(pgd_t *pgd_base) | 360 | static void __init permanent_kmaps_init(pgd_t *pgd_base) |
361 | { | 361 | { |
362 | unsigned long vaddr; | 362 | unsigned long vaddr; |
@@ -436,7 +436,6 @@ static void __init set_highmem_pages_init(void) | |||
436 | #endif /* !CONFIG_NUMA */ | 436 | #endif /* !CONFIG_NUMA */ |
437 | 437 | ||
438 | #else | 438 | #else |
439 | # define kmap_init() do { } while (0) | ||
440 | # define permanent_kmaps_init(pgd_base) do { } while (0) | 439 | # define permanent_kmaps_init(pgd_base) do { } while (0) |
441 | # define set_highmem_pages_init() do { } while (0) | 440 | # define set_highmem_pages_init() do { } while (0) |
442 | #endif /* CONFIG_HIGHMEM */ | 441 | #endif /* CONFIG_HIGHMEM */ |
diff --git a/arch/x86/mm/iomap_32.c b/arch/x86/mm/iomap_32.c new file mode 100644 index 000000000000..d0151d8ce452 --- /dev/null +++ b/arch/x86/mm/iomap_32.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * Copyright © 2008 Ingo Molnar | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but | ||
10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
17 | */ | ||
18 | |||
19 | #include <asm/iomap.h> | ||
20 | #include <linux/module.h> | ||
21 | |||
22 | /* Map 'pfn' using fixed map 'type' and protections 'prot' | ||
23 | */ | ||
24 | void * | ||
25 | iomap_atomic_prot_pfn(unsigned long pfn, enum km_type type, pgprot_t prot) | ||
26 | { | ||
27 | enum fixed_addresses idx; | ||
28 | unsigned long vaddr; | ||
29 | |||
30 | pagefault_disable(); | ||
31 | |||
32 | idx = type + KM_TYPE_NR*smp_processor_id(); | ||
33 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
34 | set_pte(kmap_pte-idx, pfn_pte(pfn, prot)); | ||
35 | arch_flush_lazy_mmu_mode(); | ||
36 | |||
37 | return (void*) vaddr; | ||
38 | } | ||
39 | EXPORT_SYMBOL_GPL(iomap_atomic_prot_pfn); | ||
40 | |||
41 | void | ||
42 | iounmap_atomic(void *kvaddr, enum km_type type) | ||
43 | { | ||
44 | unsigned long vaddr = (unsigned long) kvaddr & PAGE_MASK; | ||
45 | enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); | ||
46 | |||
47 | /* | ||
48 | * Force other mappings to Oops if they'll try to access this pte | ||
49 | * without first remap it. Keeping stale mappings around is a bad idea | ||
50 | * also, in case the page changes cacheability attributes or becomes | ||
51 | * a protected page in a hypervisor. | ||
52 | */ | ||
53 | if (vaddr == __fix_to_virt(FIX_KMAP_BEGIN+idx)) | ||
54 | kpte_clear_flush(kmap_pte-idx, vaddr); | ||
55 | |||
56 | arch_flush_lazy_mmu_mode(); | ||
57 | pagefault_enable(); | ||
58 | } | ||
59 | EXPORT_SYMBOL_GPL(iounmap_atomic); | ||