Annotation of /trunk/kernel26-alx/patches-2.6.27-r3/0143-2.6.27.44-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: 6607 byte(s)
Thu Oct 14 15:11:06 2010 UTC (13 years, 11 months ago) by niro
File size: 6607 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 | niro | 1176 | diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c |
2 | index 73cb6a3..15a369e 100644 | ||
3 | --- a/arch/powerpc/kernel/align.c | ||
4 | +++ b/arch/powerpc/kernel/align.c | ||
5 | @@ -641,10 +641,14 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, | ||
6 | */ | ||
7 | static int emulate_vsx(unsigned char __user *addr, unsigned int reg, | ||
8 | unsigned int areg, struct pt_regs *regs, | ||
9 | - unsigned int flags, unsigned int length) | ||
10 | + unsigned int flags, unsigned int length, | ||
11 | + unsigned int elsize) | ||
12 | { | ||
13 | char *ptr; | ||
14 | + unsigned long *lptr; | ||
15 | int ret = 0; | ||
16 | + int sw = 0; | ||
17 | + int i, j; | ||
18 | |||
19 | flush_vsx_to_thread(current); | ||
20 | |||
21 | @@ -653,19 +657,35 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, | ||
22 | else | ||
23 | ptr = (char *) ¤t->thread.vr[reg - 32]; | ||
24 | |||
25 | - if (flags & ST) | ||
26 | - ret = __copy_to_user(addr, ptr, length); | ||
27 | - else { | ||
28 | - if (flags & SPLT){ | ||
29 | - ret = __copy_from_user(ptr, addr, length); | ||
30 | - ptr += length; | ||
31 | + lptr = (unsigned long *) ptr; | ||
32 | + | ||
33 | + if (flags & SW) | ||
34 | + sw = elsize-1; | ||
35 | + | ||
36 | + for (j = 0; j < length; j += elsize) { | ||
37 | + for (i = 0; i < elsize; ++i) { | ||
38 | + if (flags & ST) | ||
39 | + ret |= __put_user(ptr[i^sw], addr + i); | ||
40 | + else | ||
41 | + ret |= __get_user(ptr[i^sw], addr + i); | ||
42 | } | ||
43 | - ret |= __copy_from_user(ptr, addr, length); | ||
44 | + ptr += elsize; | ||
45 | + addr += elsize; | ||
46 | } | ||
47 | - if (flags & U) | ||
48 | - regs->gpr[areg] = regs->dar; | ||
49 | - if (ret) | ||
50 | + | ||
51 | + if (!ret) { | ||
52 | + if (flags & U) | ||
53 | + regs->gpr[areg] = regs->dar; | ||
54 | + | ||
55 | + /* Splat load copies the same data to top and bottom 8 bytes */ | ||
56 | + if (flags & SPLT) | ||
57 | + lptr[1] = lptr[0]; | ||
58 | + /* For 8 byte loads, zero the top 8 bytes */ | ||
59 | + else if (!(flags & ST) && (8 == length)) | ||
60 | + lptr[1] = 0; | ||
61 | + } else | ||
62 | return -EFAULT; | ||
63 | + | ||
64 | return 1; | ||
65 | } | ||
66 | #endif | ||
67 | @@ -764,16 +784,25 @@ int fix_alignment(struct pt_regs *regs) | ||
68 | |||
69 | #ifdef CONFIG_VSX | ||
70 | if ((instruction & 0xfc00003e) == 0x7c000018) { | ||
71 | - /* Additional register addressing bit (64 VSX vs 32 FPR/GPR */ | ||
72 | + unsigned int elsize; | ||
73 | + | ||
74 | + /* Additional register addressing bit (64 VSX vs 32 FPR/GPR) */ | ||
75 | reg |= (instruction & 0x1) << 5; | ||
76 | /* Simple inline decoder instead of a table */ | ||
77 | + /* VSX has only 8 and 16 byte memory accesses */ | ||
78 | + nb = 8; | ||
79 | if (instruction & 0x200) | ||
80 | nb = 16; | ||
81 | - else if (instruction & 0x080) | ||
82 | - nb = 8; | ||
83 | - else | ||
84 | - nb = 4; | ||
85 | + | ||
86 | + /* Vector stores in little-endian mode swap individual | ||
87 | + elements, so process them separately */ | ||
88 | + elsize = 4; | ||
89 | + if (instruction & 0x80) | ||
90 | + elsize = 8; | ||
91 | + | ||
92 | flags = 0; | ||
93 | + if (regs->msr & MSR_LE) | ||
94 | + flags |= SW; | ||
95 | if (instruction & 0x100) | ||
96 | flags |= ST; | ||
97 | if (instruction & 0x040) | ||
98 | @@ -783,7 +812,7 @@ int fix_alignment(struct pt_regs *regs) | ||
99 | flags |= SPLT; | ||
100 | nb = 8; | ||
101 | } | ||
102 | - return emulate_vsx(addr, reg, areg, regs, flags, nb); | ||
103 | + return emulate_vsx(addr, reg, areg, regs, flags, nb, elsize); | ||
104 | } | ||
105 | #endif | ||
106 | /* A size of 0 indicates an instruction we don't support, with | ||
107 | diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S | ||
108 | index a088c06..2436df3 100644 | ||
109 | --- a/arch/powerpc/kernel/fpu.S | ||
110 | +++ b/arch/powerpc/kernel/fpu.S | ||
111 | @@ -145,6 +145,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX) | ||
112 | beq 1f | ||
113 | PPC_LL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
114 | li r3,MSR_FP|MSR_FE0|MSR_FE1 | ||
115 | +#ifdef CONFIG_VSX | ||
116 | +BEGIN_FTR_SECTION | ||
117 | + oris r3,r3,MSR_VSX@h | ||
118 | +END_FTR_SECTION_IFSET(CPU_FTR_VSX) | ||
119 | +#endif | ||
120 | andc r4,r4,r3 /* disable FP for previous task */ | ||
121 | PPC_STL r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
122 | 1: | ||
123 | diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S | ||
124 | index 4dd70cf..f6a2372 100644 | ||
125 | --- a/arch/powerpc/kernel/misc_64.S | ||
126 | +++ b/arch/powerpc/kernel/misc_64.S | ||
127 | @@ -493,7 +493,15 @@ _GLOBAL(giveup_altivec) | ||
128 | stvx vr0,r4,r3 | ||
129 | beq 1f | ||
130 | ld r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
131 | +#ifdef CONFIG_VSX | ||
132 | +BEGIN_FTR_SECTION | ||
133 | + lis r3,(MSR_VEC|MSR_VSX)@h | ||
134 | +FTR_SECTION_ELSE | ||
135 | + lis r3,MSR_VEC@h | ||
136 | +ALT_FTR_SECTION_END_IFSET(CPU_FTR_VSX) | ||
137 | +#else | ||
138 | lis r3,MSR_VEC@h | ||
139 | +#endif | ||
140 | andc r4,r4,r3 /* disable FP for previous task */ | ||
141 | std r4,_MSR-STACK_FRAME_OVERHEAD(r5) | ||
142 | 1: | ||
143 | diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c | ||
144 | index 894b599..ef96b29 100644 | ||
145 | --- a/kernel/audit_tree.c | ||
146 | +++ b/kernel/audit_tree.c | ||
147 | @@ -276,7 +276,7 @@ static void untag_chunk(struct node *p) | ||
148 | owner->root = NULL; | ||
149 | } | ||
150 | |||
151 | - for (i = j = 0; i < size; i++, j++) { | ||
152 | + for (i = j = 0; j <= size; i++, j++) { | ||
153 | struct audit_tree *s; | ||
154 | if (&chunk->owners[j] == p) { | ||
155 | list_del_init(&p->list); | ||
156 | @@ -289,7 +289,7 @@ static void untag_chunk(struct node *p) | ||
157 | if (!s) /* result of earlier fallback */ | ||
158 | continue; | ||
159 | get_tree(s); | ||
160 | - list_replace_init(&chunk->owners[i].list, &new->owners[j].list); | ||
161 | + list_replace_init(&chunk->owners[j].list, &new->owners[i].list); | ||
162 | } | ||
163 | |||
164 | list_replace_rcu(&chunk->hash, &new->hash); | ||
165 | @@ -372,15 +372,17 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | ||
166 | for (n = 0; n < old->count; n++) { | ||
167 | if (old->owners[n].owner == tree) { | ||
168 | spin_unlock(&hash_lock); | ||
169 | - put_inotify_watch(watch); | ||
170 | + put_inotify_watch(&old->watch); | ||
171 | return 0; | ||
172 | } | ||
173 | } | ||
174 | spin_unlock(&hash_lock); | ||
175 | |||
176 | chunk = alloc_chunk(old->count + 1); | ||
177 | - if (!chunk) | ||
178 | + if (!chunk) { | ||
179 | + put_inotify_watch(&old->watch); | ||
180 | return -ENOMEM; | ||
181 | + } | ||
182 | |||
183 | mutex_lock(&inode->inotify_mutex); | ||
184 | if (inotify_clone_watch(&old->watch, &chunk->watch) < 0) { | ||
185 | @@ -422,7 +424,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | ||
186 | spin_unlock(&hash_lock); | ||
187 | inotify_evict_watch(&old->watch); | ||
188 | mutex_unlock(&inode->inotify_mutex); | ||
189 | - put_inotify_watch(&old->watch); | ||
190 | + put_inotify_watch(&old->watch); /* pair to inotify_find_watch */ | ||
191 | + put_inotify_watch(&old->watch); /* and kill it */ | ||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | diff --git a/kernel/signal.c b/kernel/signal.c | ||
196 | index de2b649..efcdc95 100644 | ||
197 | --- a/kernel/signal.c | ||
198 | +++ b/kernel/signal.c | ||
199 | @@ -884,7 +884,8 @@ static void print_fatal_signal(struct pt_regs *regs, int signr) | ||
200 | for (i = 0; i < 16; i++) { | ||
201 | unsigned char insn; | ||
202 | |||
203 | - __get_user(insn, (unsigned char *)(regs->ip + i)); | ||
204 | + if (get_user(insn, (unsigned char *)(regs->ip + i))) | ||
205 | + break; | ||
206 | printk("%02x ", insn); | ||
207 | } | ||
208 | } | ||
209 | diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c | ||
210 | index 32afff8..d6beca9 100644 | ||
211 | --- a/net/bridge/netfilter/ebtables.c | ||
212 | +++ b/net/bridge/netfilter/ebtables.c | ||
213 | @@ -1436,6 +1436,9 @@ static int do_ebt_set_ctl(struct sock *sk, | ||
214 | { | ||
215 | int ret; | ||
216 | |||
217 | + if (!capable(CAP_NET_ADMIN)) | ||
218 | + return -EPERM; | ||
219 | + | ||
220 | switch(cmd) { | ||
221 | case EBT_SO_SET_ENTRIES: | ||
222 | ret = do_replace(user, len); | ||
223 | @@ -1455,6 +1458,9 @@ static int do_ebt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | ||
224 | struct ebt_replace tmp; | ||
225 | struct ebt_table *t; | ||
226 | |||
227 | + if (!capable(CAP_NET_ADMIN)) | ||
228 | + return -EPERM; | ||
229 | + | ||
230 | if (copy_from_user(&tmp, user, sizeof(tmp))) | ||
231 | return -EFAULT; | ||
232 |