Magellan Linux

Contents of /trunk/kernel26-alx/patches-2.6.27-r3/0143-2.6.27.44-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1176 - (show annotations) (download)
Thu Oct 14 15:11:06 2010 UTC (13 years, 6 months ago) by niro
File size: 6607 byte(s)
-2.6.27-alx-r3: new magellan 0.5.2 kernel
1 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 *) &current->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