Magellan Linux

Annotation 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 - (hide annotations) (download)
Thu Jul 10 13:03:47 2008 UTC (15 years, 10 months ago) by niro
File size: 15530 byte(s)
-2.6.25-magellan-r4; updated to linux-2.6.25.10

1 niro 664 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     }