Magellan Linux

Contents of /trunk/kernel26-magellan/patches-2.6.25-r4/0109-2.6.25.10-all-fixes.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 664 - (show annotations) (download)
Thu Jul 10 13:03:47 2008 UTC (15 years, 9 months ago) by niro
File size: 15530 byte(s)
-2.6.25-magellan-r4; updated to linux-2.6.25.10

1 diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c
2 index d2e39e6..5f04579 100644
3 --- a/arch/x86/kernel/i387.c
4 +++ b/arch/x86/kernel/i387.c
5 @@ -130,7 +130,7 @@ int xfpregs_get(struct task_struct *target, const struct user_regset *regset,
6 void *kbuf, void __user *ubuf)
7 {
8 if (!cpu_has_fxsr)
9 - return -ENODEV;
10 + return -EIO;
11
12 init_fpu(target);
13
14 @@ -145,7 +145,7 @@ int xfpregs_set(struct task_struct *target, const struct user_regset *regset,
15 int ret;
16
17 if (!cpu_has_fxsr)
18 - return -ENODEV;
19 + return -EIO;
20
21 init_fpu(target);
22 set_stopped_child_used_math(target);
23 diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
24 index 9003e0b..a10ba65 100644
25 --- a/arch/x86/kernel/ptrace.c
26 +++ b/arch/x86/kernel/ptrace.c
27 @@ -1309,42 +1309,49 @@ asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
28 break;
29
30 case PTRACE_GETREGS: /* Get all gp regs from the child. */
31 - return copy_regset_to_user(child, &user_x86_32_view,
32 - REGSET_GENERAL,
33 - 0, sizeof(struct user_regs_struct32),
34 - datap);
35 + ret = copy_regset_to_user(child, &user_x86_32_view,
36 + REGSET_GENERAL,
37 + 0, sizeof(struct user_regs_struct32),
38 + datap);
39 + break;
40
41 case PTRACE_SETREGS: /* Set all gp regs in the child. */
42 - return copy_regset_from_user(child, &user_x86_32_view,
43 - REGSET_GENERAL, 0,
44 - sizeof(struct user_regs_struct32),
45 - datap);
46 + ret = copy_regset_from_user(child, &user_x86_32_view,
47 + REGSET_GENERAL, 0,
48 + sizeof(struct user_regs_struct32),
49 + datap);
50 + break;
51
52 case PTRACE_GETFPREGS: /* Get the child FPU state. */
53 - return copy_regset_to_user(child, &user_x86_32_view,
54 - REGSET_FP, 0,
55 - sizeof(struct user_i387_ia32_struct),
56 - datap);
57 + ret = copy_regset_to_user(child, &user_x86_32_view,
58 + REGSET_FP, 0,
59 + sizeof(struct user_i387_ia32_struct),
60 + datap);
61 + break;
62
63 case PTRACE_SETFPREGS: /* Set the child FPU state. */
64 - return copy_regset_from_user(
65 + ret = copy_regset_from_user(
66 child, &user_x86_32_view, REGSET_FP,
67 0, sizeof(struct user_i387_ia32_struct), datap);
68 + break;
69
70 case PTRACE_GETFPXREGS: /* Get the child extended FPU state. */
71 - return copy_regset_to_user(child, &user_x86_32_view,
72 - REGSET_XFP, 0,
73 - sizeof(struct user32_fxsr_struct),
74 - datap);
75 + ret = copy_regset_to_user(child, &user_x86_32_view,
76 + REGSET_XFP, 0,
77 + sizeof(struct user32_fxsr_struct),
78 + datap);
79 + break;
80
81 case PTRACE_SETFPXREGS: /* Set the child extended FPU state. */
82 - return copy_regset_from_user(child, &user_x86_32_view,
83 + ret = copy_regset_from_user(child, &user_x86_32_view,
84 REGSET_XFP, 0,
85 sizeof(struct user32_fxsr_struct),
86 datap);
87 + break;
88
89 default:
90 - return compat_ptrace_request(child, request, addr, data);
91 + ret = compat_ptrace_request(child, request, addr, data);
92 + break;
93 }
94
95 out:
96 diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
97 index 0880f2c..7b768e3 100644
98 --- a/arch/x86/kernel/smpboot_64.c
99 +++ b/arch/x86/kernel/smpboot_64.c
100 @@ -704,7 +704,6 @@ do_rest:
101 clear_bit(cpu, (unsigned long *)&cpu_initialized); /* was set by cpu_init() */
102 clear_node_cpumask(cpu); /* was set by numa_add_cpu */
103 cpu_clear(cpu, cpu_present_map);
104 - cpu_clear(cpu, cpu_possible_map);
105 per_cpu(x86_cpu_to_apicid, cpu) = BAD_APICID;
106 return -EIO;
107 }
108 diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
109 index b2b451d..becab51 100644
110 --- a/drivers/char/drm/i915_drv.c
111 +++ b/drivers/char/drm/i915_drv.c
112 @@ -385,6 +385,7 @@ static int i915_resume(struct drm_device *dev)
113 pci_restore_state(dev->pdev);
114 if (pci_enable_device(dev->pdev))
115 return -1;
116 + pci_set_master(dev->pdev);
117
118 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
119
120 diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
121 index 252db08..0b92d3e 100644
122 --- a/drivers/infiniband/hw/mthca/mthca_memfree.c
123 +++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
124 @@ -109,7 +109,11 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
125 {
126 struct page *page;
127
128 - page = alloc_pages(gfp_mask, order);
129 + /*
130 + * Use __GFP_ZERO because buggy firmware assumes ICM pages are
131 + * cleared, and subtle failures are seen if they aren't.
132 + */
133 + page = alloc_pages(gfp_mask | __GFP_ZERO, order);
134 if (!page)
135 return -ENOMEM;
136
137 diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
138 index 0a9b751..756e1bb 100644
139 --- a/drivers/net/hamradio/6pack.c
140 +++ b/drivers/net/hamradio/6pack.c
141 @@ -601,6 +601,8 @@ static int sixpack_open(struct tty_struct *tty)
142
143 if (!capable(CAP_NET_ADMIN))
144 return -EPERM;
145 + if (!tty->driver->write)
146 + return -EOPNOTSUPP;
147
148 dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
149 if (!dev) {
150 diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
151 index 30c9b3b..f650da3 100644
152 --- a/drivers/net/hamradio/mkiss.c
153 +++ b/drivers/net/hamradio/mkiss.c
154 @@ -529,6 +529,7 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
155 static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
156 {
157 struct mkiss *ax = netdev_priv(dev);
158 + int cib = 0;
159
160 if (!netif_running(dev)) {
161 printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
162 @@ -544,10 +545,11 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
163 /* 20 sec timeout not reached */
164 return 1;
165 }
166 + if (ax->tty->driver->chars_in_buffer)
167 + cib = ax->tty->driver->chars_in_buffer(ax->tty);
168
169 printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
170 - (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ?
171 - "bad line quality" : "driver error");
172 + cib || ax->xleft ? "bad line quality" : "driver error");
173
174 ax->xleft = 0;
175 clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
176 @@ -736,6 +738,8 @@ static int mkiss_open(struct tty_struct *tty)
177
178 if (!capable(CAP_NET_ADMIN))
179 return -EPERM;
180 + if (!tty->driver->write)
181 + return -EOPNOTSUPP;
182
183 dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
184 if (!dev) {
185 diff --git a/drivers/net/irda/irtty-sir.c b/drivers/net/irda/irtty-sir.c
186 index fc753d7..df755f5 100644
187 --- a/drivers/net/irda/irtty-sir.c
188 +++ b/drivers/net/irda/irtty-sir.c
189 @@ -64,7 +64,9 @@ static int irtty_chars_in_buffer(struct sir_dev *dev)
190 IRDA_ASSERT(priv != NULL, return -1;);
191 IRDA_ASSERT(priv->magic == IRTTY_MAGIC, return -1;);
192
193 - return priv->tty->driver->chars_in_buffer(priv->tty);
194 + if (priv->tty->driver->chars_in_buffer)
195 + return priv->tty->driver->chars_in_buffer(priv->tty);
196 + return 0;
197 }
198
199 /* Wait (sleep) until underlaying hardware finished transmission
200 diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
201 index f023d5b..098bf44 100644
202 --- a/drivers/net/ppp_async.c
203 +++ b/drivers/net/ppp_async.c
204 @@ -158,6 +158,9 @@ ppp_asynctty_open(struct tty_struct *tty)
205 struct asyncppp *ap;
206 int err;
207
208 + if (!tty->driver->write)
209 + return -EOPNOTSUPP;
210 +
211 err = -ENOMEM;
212 ap = kzalloc(sizeof(*ap), GFP_KERNEL);
213 if (!ap)
214 diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
215 index 0d80fa5..7372938 100644
216 --- a/drivers/net/ppp_synctty.c
217 +++ b/drivers/net/ppp_synctty.c
218 @@ -207,6 +207,9 @@ ppp_sync_open(struct tty_struct *tty)
219 struct syncppp *ap;
220 int err;
221
222 + if (!tty->driver->write)
223 + return -EOPNOTSUPP;
224 +
225 ap = kzalloc(sizeof(*ap), GFP_KERNEL);
226 err = -ENOMEM;
227 if (!ap)
228 diff --git a/drivers/net/slip.c b/drivers/net/slip.c
229 index 5a55ede..9d138bf 100644
230 --- a/drivers/net/slip.c
231 +++ b/drivers/net/slip.c
232 @@ -460,10 +460,14 @@ static void sl_tx_timeout(struct net_device *dev)
233 /* 20 sec timeout not reached */
234 goto out;
235 }
236 - printk(KERN_WARNING "%s: transmit timed out, %s?\n",
237 - dev->name,
238 - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
239 - "bad line quality" : "driver error");
240 + {
241 + int cib = 0;
242 + if (sl->tty->driver->chars_in_buffer)
243 + cib = sl->tty->driver->chars_in_buffer(sl->tty);
244 + printk(KERN_WARNING "%s: transmit timed out, %s?\n",
245 + dev->name, (cib || sl->xleft) ?
246 + "bad line quality" : "driver error");
247 + }
248 sl->xleft = 0;
249 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
250 sl_unlock(sl);
251 @@ -829,6 +833,8 @@ static int slip_open(struct tty_struct *tty)
252
253 if (!capable(CAP_NET_ADMIN))
254 return -EPERM;
255 + if (!tty->driver->write)
256 + return -EOPNOTSUPP;
257
258 /* RTnetlink lock is misused here to serialize concurrent
259 opens of slip channels. There are better ways, but it is
260 diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c
261 index 0f8aca8..f5b9a71 100644
262 --- a/drivers/net/wan/x25_asy.c
263 +++ b/drivers/net/wan/x25_asy.c
264 @@ -283,6 +283,10 @@ static void x25_asy_write_wakeup(struct tty_struct *tty)
265 static void x25_asy_timeout(struct net_device *dev)
266 {
267 struct x25_asy *sl = (struct x25_asy*)(dev->priv);
268 + int cib = 0;
269 +
270 + if (sl->tty->driver->chars_in_buffer)
271 + cib = sl->tty->driver->chars_in_buffer(sl->tty);
272
273 spin_lock(&sl->lock);
274 if (netif_queue_stopped(dev)) {
275 @@ -290,8 +294,7 @@ static void x25_asy_timeout(struct net_device *dev)
276 * 14 Oct 1994 Dmitry Gorodchanin.
277 */
278 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
279 - (sl->tty->driver->chars_in_buffer(sl->tty) || sl->xleft) ?
280 - "bad line quality" : "driver error");
281 + (cib || sl->xleft) ? "bad line quality" : "driver error");
282 sl->xleft = 0;
283 sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
284 x25_asy_unlock(sl);
285 @@ -561,6 +564,9 @@ static int x25_asy_open_tty(struct tty_struct *tty)
286 return -EEXIST;
287 }
288
289 + if (!tty->driver->write)
290 + return -EOPNOTSUPP;
291 +
292 /* OK. Find a free X.25 channel to use. */
293 if ((sl = x25_asy_alloc()) == NULL) {
294 return -ENFILE;
295 diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
296 index 88efe1b..5536a94 100644
297 --- a/drivers/net/wireless/strip.c
298 +++ b/drivers/net/wireless/strip.c
299 @@ -802,7 +802,8 @@ static void set_baud(struct tty_struct *tty, unsigned int baudcode)
300 struct ktermios old_termios = *(tty->termios);
301 tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */
302 tty->termios->c_cflag |= baudcode; /* Set the new baud setting */
303 - tty->driver->set_termios(tty, &old_termios);
304 + if (tty->driver->set_termios)
305 + tty->driver->set_termios(tty, &old_termios);
306 }
307
308 /*
309 diff --git a/include/asm-x86/msr.h b/include/asm-x86/msr.h
310 index 3ca29eb..84a15b6 100644
311 --- a/include/asm-x86/msr.h
312 +++ b/include/asm-x86/msr.h
313 @@ -18,7 +18,7 @@ static inline unsigned long long native_read_tscp(unsigned int *aux)
314 unsigned long low, high;
315 asm volatile (".byte 0x0f,0x01,0xf9"
316 : "=a" (low), "=d" (high), "=c" (*aux));
317 - return low | ((u64)high >> 32);
318 + return low | ((u64)high << 32);
319 }
320
321 /*
322 diff --git a/kernel/futex.c b/kernel/futex.c
323 index e43945e..cc6fd0d 100644
324 --- a/kernel/futex.c
325 +++ b/kernel/futex.c
326 @@ -1118,21 +1118,64 @@ static void unqueue_me_pi(struct futex_q *q)
327 * private futexes.
328 */
329 static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
330 - struct task_struct *newowner)
331 + struct task_struct *newowner,
332 + struct rw_semaphore *fshared)
333 {
334 u32 newtid = task_pid_vnr(newowner) | FUTEX_WAITERS;
335 struct futex_pi_state *pi_state = q->pi_state;
336 + struct task_struct *oldowner = pi_state->owner;
337 u32 uval, curval, newval;
338 - int ret;
339 + int ret, attempt = 0;
340
341 /* Owner died? */
342 + if (!pi_state->owner)
343 + newtid |= FUTEX_OWNER_DIED;
344 +
345 + /*
346 + * We are here either because we stole the rtmutex from the
347 + * pending owner or we are the pending owner which failed to
348 + * get the rtmutex. We have to replace the pending owner TID
349 + * in the user space variable. This must be atomic as we have
350 + * to preserve the owner died bit here.
351 + *
352 + * Note: We write the user space value _before_ changing the
353 + * pi_state because we can fault here. Imagine swapped out
354 + * pages or a fork, which was running right before we acquired
355 + * mmap_sem, that marked all the anonymous memory readonly for
356 + * cow.
357 + *
358 + * Modifying pi_state _before_ the user space value would
359 + * leave the pi_state in an inconsistent state when we fault
360 + * here, because we need to drop the hash bucket lock to
361 + * handle the fault. This might be observed in the PID check
362 + * in lookup_pi_state.
363 + */
364 +retry:
365 + if (get_futex_value_locked(&uval, uaddr))
366 + goto handle_fault;
367 +
368 + while (1) {
369 + newval = (uval & FUTEX_OWNER_DIED) | newtid;
370 +
371 + curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
372 +
373 + if (curval == -EFAULT)
374 + goto handle_fault;
375 + if (curval == uval)
376 + break;
377 + uval = curval;
378 + }
379 +
380 + /*
381 + * We fixed up user space. Now we need to fix the pi_state
382 + * itself.
383 + */
384 if (pi_state->owner != NULL) {
385 spin_lock_irq(&pi_state->owner->pi_lock);
386 WARN_ON(list_empty(&pi_state->list));
387 list_del_init(&pi_state->list);
388 spin_unlock_irq(&pi_state->owner->pi_lock);
389 - } else
390 - newtid |= FUTEX_OWNER_DIED;
391 + }
392
393 pi_state->owner = newowner;
394
395 @@ -1140,26 +1183,35 @@ static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
396 WARN_ON(!list_empty(&pi_state->list));
397 list_add(&pi_state->list, &newowner->pi_state_list);
398 spin_unlock_irq(&newowner->pi_lock);
399 + return 0;
400
401 /*
402 - * We own it, so we have to replace the pending owner
403 - * TID. This must be atomic as we have preserve the
404 - * owner died bit here.
405 + * To handle the page fault we need to drop the hash bucket
406 + * lock here. That gives the other task (either the pending
407 + * owner itself or the task which stole the rtmutex) the
408 + * chance to try the fixup of the pi_state. So once we are
409 + * back from handling the fault we need to check the pi_state
410 + * after reacquiring the hash bucket lock and before trying to
411 + * do another fixup. When the fixup has been done already we
412 + * simply return.
413 */
414 - ret = get_futex_value_locked(&uval, uaddr);
415 +handle_fault:
416 + spin_unlock(q->lock_ptr);
417
418 - while (!ret) {
419 - newval = (uval & FUTEX_OWNER_DIED) | newtid;
420 + ret = futex_handle_fault((unsigned long)uaddr, fshared, attempt++);
421
422 - curval = cmpxchg_futex_value_locked(uaddr, uval, newval);
423 + spin_lock(q->lock_ptr);
424
425 - if (curval == -EFAULT)
426 - ret = -EFAULT;
427 - if (curval == uval)
428 - break;
429 - uval = curval;
430 - }
431 - return ret;
432 + /*
433 + * Check if someone else fixed it for us:
434 + */
435 + if (pi_state->owner != oldowner)
436 + return 0;
437 +
438 + if (ret)
439 + return ret;
440 +
441 + goto retry;
442 }
443
444 /*
445 @@ -1524,7 +1576,7 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
446 * that case:
447 */
448 if (q.pi_state->owner != curr)
449 - ret = fixup_pi_state_owner(uaddr, &q, curr);
450 + ret = fixup_pi_state_owner(uaddr, &q, curr, fshared);
451 } else {
452 /*
453 * Catch the rare case, where the lock was released
454 @@ -1556,7 +1608,8 @@ static int futex_lock_pi(u32 __user *uaddr, struct rw_semaphore *fshared,
455 int res;
456
457 owner = rt_mutex_owner(&q.pi_state->pi_mutex);
458 - res = fixup_pi_state_owner(uaddr, &q, owner);
459 + res = fixup_pi_state_owner(uaddr, &q, owner,
460 + fshared);
461
462 /* propagate -EFAULT, if the fixup failed */
463 if (res)
464 diff --git a/kernel/sched.c b/kernel/sched.c
465 index 1e4596c..c54077c 100644
466 --- a/kernel/sched.c
467 +++ b/kernel/sched.c
468 @@ -5728,6 +5728,7 @@ static void migrate_dead_tasks(unsigned int dead_cpu)
469 next = pick_next_task(rq, rq->curr);
470 if (!next)
471 break;
472 + next->sched_class->put_prev_task(rq, next);
473 migrate_dead(dead_cpu, next);
474
475 }