aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:03:36 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-25 15:03:36 -0400
commitdd0e101d630b0d7ed6c9e1ccf7af7fc91818330e (patch)
tree95418fcada0506baa001be22b1202ead681e08ca
parentcf2ec150fc5f59dbf2260863225c79aa0cfc46af (diff)
parent00c6b2d5d7b2414bd46c620d6a8c37fa7a716f29 (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.c39
-rw-r--r--arch/x86/mm/init_64.c7
-rw-r--r--include/asm-x86/fixmap.h8
-rw-r--r--include/asm-x86/fixmap_32.h7
-rw-r--r--include/asm-x86/fixmap_64.h4
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
138static __init void 138static void
139set_pte_phys(unsigned long vaddr, unsigned long phys, pgprot_t prot) 139set_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 */
217void __init 217void __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>