diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 15:03:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-25 15:03:36 -0400 |
commit | dd0e101d630b0d7ed6c9e1ccf7af7fc91818330e (patch) | |
tree | 95418fcada0506baa001be22b1202ead681e08ca | |
parent | cf2ec150fc5f59dbf2260863225c79aa0cfc46af (diff) | |
parent | 00c6b2d5d7b2414bd46c620d6a8c37fa7a716f29 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-x86-fixes4
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mingo/linux-2.6-x86-fixes4:
x86: harden kernel code patching
x86: clean up text_poke()
x86: fix text_poke()
x86: remove set_fixmap() warning
x86: make __set_fixmap() non-init
x86: make clear_fixmap() available on 64-bit as well
-rw-r--r-- | arch/x86/kernel/alternative.c | 39 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 7 | ||||
-rw-r--r-- | include/asm-x86/fixmap.h | 8 | ||||
-rw-r--r-- | include/asm-x86/fixmap_32.h | 7 | ||||
-rw-r--r-- | include/asm-x86/fixmap_64.h | 4 |
5 files changed, 34 insertions, 31 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index df4099dc1c68..65c7857a90dd 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -511,31 +511,30 @@ void *__kprobes text_poke(void *addr, const void *opcode, size_t len) | |||
511 | unsigned long flags; | 511 | unsigned long flags; |
512 | char *vaddr; | 512 | char *vaddr; |
513 | int nr_pages = 2; | 513 | int nr_pages = 2; |
514 | struct page *pages[2]; | ||
515 | int i; | ||
514 | 516 | ||
515 | BUG_ON(len > sizeof(long)); | 517 | if (!core_kernel_text((unsigned long)addr)) { |
516 | BUG_ON((((long)addr + len - 1) & ~(sizeof(long) - 1)) | 518 | pages[0] = vmalloc_to_page(addr); |
517 | - ((long)addr & ~(sizeof(long) - 1))); | 519 | pages[1] = vmalloc_to_page(addr + PAGE_SIZE); |
518 | if (kernel_text_address((unsigned long)addr)) { | ||
519 | struct page *pages[2] = { virt_to_page(addr), | ||
520 | virt_to_page(addr + PAGE_SIZE) }; | ||
521 | if (!pages[1]) | ||
522 | nr_pages = 1; | ||
523 | vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); | ||
524 | BUG_ON(!vaddr); | ||
525 | local_irq_save(flags); | ||
526 | memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); | ||
527 | local_irq_restore(flags); | ||
528 | vunmap(vaddr); | ||
529 | } else { | 520 | } else { |
530 | /* | 521 | pages[0] = virt_to_page(addr); |
531 | * modules are in vmalloc'ed memory, always writable. | 522 | WARN_ON(!PageReserved(pages[0])); |
532 | */ | 523 | pages[1] = virt_to_page(addr + PAGE_SIZE); |
533 | local_irq_save(flags); | ||
534 | memcpy(addr, opcode, len); | ||
535 | local_irq_restore(flags); | ||
536 | } | 524 | } |
525 | BUG_ON(!pages[0]); | ||
526 | if (!pages[1]) | ||
527 | nr_pages = 1; | ||
528 | vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL); | ||
529 | BUG_ON(!vaddr); | ||
530 | local_irq_save(flags); | ||
531 | memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len); | ||
532 | local_irq_restore(flags); | ||
533 | vunmap(vaddr); | ||
537 | sync_core(); | 534 | sync_core(); |
538 | /* Could also do a CLFLUSH here to speed up CPU recovery; but | 535 | /* Could also do a CLFLUSH here to speed up CPU recovery; but |
539 | that causes hangs on some VIA CPUs. */ | 536 | that causes hangs on some VIA CPUs. */ |
537 | for (i = 0; i < len; i++) | ||
538 | BUG_ON(((char *)addr)[i] != ((char *)opcode)[i]); | ||
540 | return addr; | 539 | return addr; |
541 | } | 540 | } |
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 1ff7906a9a4d..b798e7b92b17 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -135,7 +135,7 @@ static __init void *spp_getpage(void) | |||
135 | return ptr; | 135 | return ptr; |
136 | } | 136 | } |
137 | 137 | ||
138 | static __init void | 138 | static void |
139 | set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) | 139 | set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) |
140 | { | 140 | { |
141 | pgd_t *pgd; | 141 | pgd_t *pgd; |
@@ -173,7 +173,7 @@ set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) | |||
173 | new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); | 173 | new_pte = pfn_pte(phys >> PAGE_SHIFT, prot); |
174 | 174 | ||
175 | pte = pte_offset_kernel(pmd, vaddr); | 175 | pte = pte_offset_kernel(pmd, vaddr); |
176 | if (!pte_none(*pte) && | 176 | if (!pte_none(*pte) && pte_val(new_pte) && |
177 | pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) | 177 | pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask)) |
178 | pte_ERROR(*pte); | 178 | pte_ERROR(*pte); |
179 | set_pte(pte, new_pte); | 179 | set_pte(pte, new_pte); |
@@ -214,8 +214,7 @@ void __init cleanup_highmap(void) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* NOTE: this is meant to be run only at boot */ | 216 | /* NOTE: this is meant to be run only at boot */ |
217 | void __init | 217 | void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) |
218 | __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t prot) | ||
219 | { | 218 | { |
220 | unsigned long address = __fix_to_virt(idx); | 219 | unsigned long address = __fix_to_virt(idx); |
221 | 220 | ||
diff --git a/include/asm-x86/fixmap.h b/include/asm-x86/fixmap.h index 382eb271a892..5bd206973dca 100644 --- a/include/asm-x86/fixmap.h +++ b/include/asm-x86/fixmap.h | |||
@@ -1,5 +1,13 @@ | |||
1 | #ifndef _ASM_FIXMAP_H | ||
2 | #define _ASM_FIXMAP_H | ||
3 | |||
1 | #ifdef CONFIG_X86_32 | 4 | #ifdef CONFIG_X86_32 |
2 | # include "fixmap_32.h" | 5 | # include "fixmap_32.h" |
3 | #else | 6 | #else |
4 | # include "fixmap_64.h" | 7 | # include "fixmap_64.h" |
5 | #endif | 8 | #endif |
9 | |||
10 | #define clear_fixmap(idx) \ | ||
11 | __set_fixmap(idx, 0, __pgprot(0)) | ||
12 | |||
13 | #endif | ||
diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h index eb1665125c44..4b96148e90c1 100644 --- a/include/asm-x86/fixmap_32.h +++ b/include/asm-x86/fixmap_32.h | |||
@@ -10,8 +10,8 @@ | |||
10 | * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 | 10 | * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #ifndef _ASM_FIXMAP_H | 13 | #ifndef _ASM_FIXMAP_32_H |
14 | #define _ASM_FIXMAP_H | 14 | #define _ASM_FIXMAP_32_H |
15 | 15 | ||
16 | 16 | ||
17 | /* used by vmalloc.c, vsyscall.lds.S. | 17 | /* used by vmalloc.c, vsyscall.lds.S. |
@@ -121,9 +121,6 @@ extern void reserve_top_address(unsigned long reserve); | |||
121 | #define set_fixmap_nocache(idx, phys) \ | 121 | #define set_fixmap_nocache(idx, phys) \ |
122 | __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) | 122 | __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) |
123 | 123 | ||
124 | #define clear_fixmap(idx) \ | ||
125 | __set_fixmap(idx, 0, __pgprot(0)) | ||
126 | |||
127 | #define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP) | 124 | #define FIXADDR_TOP ((unsigned long)__FIXADDR_TOP) |
128 | 125 | ||
129 | #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) | 126 | #define __FIXADDR_SIZE (__end_of_permanent_fixed_addresses << PAGE_SHIFT) |
diff --git a/include/asm-x86/fixmap_64.h b/include/asm-x86/fixmap_64.h index f3d76858c0e6..355d26a75a82 100644 --- a/include/asm-x86/fixmap_64.h +++ b/include/asm-x86/fixmap_64.h | |||
@@ -8,8 +8,8 @@ | |||
8 | * Copyright (C) 1998 Ingo Molnar | 8 | * Copyright (C) 1998 Ingo Molnar |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #ifndef _ASM_FIXMAP_H | 11 | #ifndef _ASM_FIXMAP_64_H |
12 | #define _ASM_FIXMAP_H | 12 | #define _ASM_FIXMAP_64_H |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <asm/apicdef.h> | 15 | #include <asm/apicdef.h> |