Annotation of /trunk/kernel26-alx/patches-2.6.27-r3/0151-2.6.27.52-all-fixes.patch
Parent Directory | Revision Log
Revision 1176 -
(hide annotations)
(download)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 3635 byte(s)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 3635 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 | niro | 1176 | diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c |
2 | index 3384255..9d3c576 100644 | ||
3 | --- a/arch/x86/mm/fault.c | ||
4 | +++ b/arch/x86/mm/fault.c | ||
5 | @@ -589,6 +589,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) | ||
6 | unsigned long address; | ||
7 | int write, si_code; | ||
8 | int fault; | ||
9 | + int should_exit_no_context = 0; | ||
10 | #ifdef CONFIG_X86_64 | ||
11 | unsigned long flags; | ||
12 | #endif | ||
13 | @@ -876,6 +877,9 @@ no_context: | ||
14 | oops_end(flags, regs, SIGKILL); | ||
15 | #endif | ||
16 | |||
17 | + if (should_exit_no_context) | ||
18 | + return; | ||
19 | + | ||
20 | /* | ||
21 | * We ran out of memory, or some other thing happened to us that made | ||
22 | * us unable to handle the page fault gracefully. | ||
23 | @@ -901,8 +905,11 @@ do_sigbus: | ||
24 | up_read(&mm->mmap_sem); | ||
25 | |||
26 | /* Kernel mode? Handle exceptions or die */ | ||
27 | - if (!(error_code & PF_USER)) | ||
28 | + if (!(error_code & PF_USER)) { | ||
29 | + should_exit_no_context = 1; | ||
30 | goto no_context; | ||
31 | + } | ||
32 | + | ||
33 | #ifdef CONFIG_X86_32 | ||
34 | /* User space => ok to do another page fault */ | ||
35 | if (is_prefetch(regs, address, error_code)) | ||
36 | diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c | ||
37 | index d8be92a..0325100 100644 | ||
38 | --- a/fs/proc/task_mmu.c | ||
39 | +++ b/fs/proc/task_mmu.c | ||
40 | @@ -205,6 +205,7 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) | ||
41 | struct file *file = vma->vm_file; | ||
42 | int flags = vma->vm_flags; | ||
43 | unsigned long ino = 0; | ||
44 | + unsigned long start; | ||
45 | dev_t dev = 0; | ||
46 | int len; | ||
47 | |||
48 | @@ -214,8 +215,13 @@ static void show_map_vma(struct seq_file *m, struct vm_area_struct *vma) | ||
49 | ino = inode->i_ino; | ||
50 | } | ||
51 | |||
52 | + /* We don't show the stack guard page in /proc/maps */ | ||
53 | + start = vma->vm_start; | ||
54 | + if (vma->vm_flags & VM_GROWSDOWN) | ||
55 | + start += PAGE_SIZE; | ||
56 | + | ||
57 | seq_printf(m, "%08lx-%08lx %c%c%c%c %08llx %02x:%02x %lu %n", | ||
58 | - vma->vm_start, | ||
59 | + start, | ||
60 | vma->vm_end, | ||
61 | flags & VM_READ ? 'r' : '-', | ||
62 | flags & VM_WRITE ? 'w' : '-', | ||
63 | diff --git a/mm/memory.c b/mm/memory.c | ||
64 | index 1300b70f..f0282eb 100644 | ||
65 | --- a/mm/memory.c | ||
66 | +++ b/mm/memory.c | ||
67 | @@ -2396,6 +2396,26 @@ out_nomap: | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | + * This is like a special single-page "expand_downwards()", | ||
72 | + * except we must first make sure that 'address-PAGE_SIZE' | ||
73 | + * doesn't hit another vma. | ||
74 | + * | ||
75 | + * The "find_vma()" will do the right thing even if we wrap | ||
76 | + */ | ||
77 | +static inline int check_stack_guard_page(struct vm_area_struct *vma, unsigned long address) | ||
78 | +{ | ||
79 | + address &= PAGE_MASK; | ||
80 | + if ((vma->vm_flags & VM_GROWSDOWN) && address == vma->vm_start) { | ||
81 | + address -= PAGE_SIZE; | ||
82 | + if (find_vma(vma->vm_mm, address) != vma) | ||
83 | + return -ENOMEM; | ||
84 | + | ||
85 | + expand_stack(vma, address); | ||
86 | + } | ||
87 | + return 0; | ||
88 | +} | ||
89 | + | ||
90 | +/* | ||
91 | * We enter with non-exclusive mmap_sem (to exclude vma changes, | ||
92 | * but allow concurrent faults), and pte mapped but not yet locked. | ||
93 | * We return with mmap_sem still held, but pte unmapped and unlocked. | ||
94 | @@ -2408,9 +2428,13 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma, | ||
95 | spinlock_t *ptl; | ||
96 | pte_t entry; | ||
97 | |||
98 | - /* Allocate our own private page. */ | ||
99 | pte_unmap(page_table); | ||
100 | |||
101 | + /* Check if we need to add a guard page to the stack */ | ||
102 | + if (check_stack_guard_page(vma, address) < 0) | ||
103 | + return VM_FAULT_SIGBUS; | ||
104 | + | ||
105 | + /* Allocate our own private page. */ | ||
106 | if (unlikely(anon_vma_prepare(vma))) | ||
107 | goto oom; | ||
108 | page = alloc_zeroed_user_highpage_movable(vma, address); | ||
109 | diff --git a/mm/mmap.c b/mm/mmap.c | ||
110 | index f3e5bfe..08a32cf 100644 | ||
111 | --- a/mm/mmap.c | ||
112 | +++ b/mm/mmap.c | ||
113 | @@ -1573,7 +1573,7 @@ static int acct_stack_growth(struct vm_area_struct * vma, unsigned long size, un | ||
114 | * Overcommit.. This must be the final test, as it will | ||
115 | * update security statistics. | ||
116 | */ | ||
117 | - if (security_vm_enough_memory(grow)) | ||
118 | + if (security_vm_enough_memory_mm(mm, grow)) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | /* Ok, everything looks good - let it rip */ |