2007-11-19 18:21:44

by Greg KH

[permalink] [raw]
Subject: [patch 00/26] 2.6.22-stable review

This is the start of the stable review cycle for the 2.6.22.14 release.
There are 26 patches in this series, all will be posted as a response to
this one. If anyone has any issues with these being applied, please let
us know. If anyone is a maintainer of the proper subsystem, and wants
to add a Signed-off-by: line to the patch, please respond with it.

These patches are sent out with a number of different people on the Cc:
line. If you wish to be a reviewer, please email [email protected] to
add your name to the list. If you want to be off the reviewer list,
also email us.

Responses should be made by Wed, Nov 21, 18:00:00 UTC. Anything
received after that time might be too late.

thanks,

greg k-h


2007-11-19 18:22:00

by Greg KH

[permalink] [raw]
Subject: [patch 02/26] Fix compat futex hangs.

From: David Miller <[email protected]>

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
[FUTEX]: Fix address computation in compat code.

[ Upstream commit: 3c5fd9c77d609b51c0bab682c9d40cbb496ec6f1 ]

compat_exit_robust_list() computes a pointer to the
futex entry in userspace as follows:

(void __user *)entry + futex_offset

'entry' is a 'struct robust_list __user *', and
'futex_offset' is a 'compat_long_t' (typically a 's32').

Things explode if the 32-bit sign bit is set in futex_offset.

Type promotion sign extends futex_offset to a 64-bit value before
adding it to 'entry'.

This triggered a problem on sparc64 running 32-bit applications which
would lock up a cpu looping forever in the fault handling for the
userspace load in handle_futex_death().

Compat userspace runs with address masking (wherein the cpu zeros out
the top 32-bits of every effective address given to a memory operation
instruction) so the sparc64 fault handler accounts for this by
zero'ing out the top 32-bits of the fault address too.

Since the kernel properly uses the compat_uptr interfaces, kernel side
accesses to compat userspace work too since they will only use
addresses with the top 32-bit clear.

Because of this compat futex layer bug we get into the following loop
when executing the get_user() load near the top of handle_futex_death():

1) load from address '0xfffffffff7f16bd8', FAULT
2) fault handler clears upper 32-bits, processes fault
for address '0xf7f16bd8' which succeeds
3) goto #1

I want to thank Bernd Zeimetz, Josip Rodin, and Fabio Massimo Di Nitto
for their tireless efforts helping me track down this bug.

Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
kernel/futex_compat.c | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)

--- a/kernel/futex_compat.c
+++ b/kernel/futex_compat.c
@@ -29,6 +29,15 @@ fetch_robust_entry(compat_uptr_t *uentry
return 0;
}

+static void __user *futex_uaddr(struct robust_list *entry,
+ compat_long_t futex_offset)
+{
+ compat_uptr_t base = ptr_to_compat(entry);
+ void __user *uaddr = compat_ptr(base + futex_offset);
+
+ return uaddr;
+}
+
/*
* Walk curr->robust_list (very carefully, it's a userspace list!)
* and mark any locks found there dead, and notify any waiters.
@@ -61,18 +70,23 @@ void compat_exit_robust_list(struct task
if (fetch_robust_entry(&upending, &pending,
&head->list_op_pending, &pip))
return;
- if (pending)
- handle_futex_death((void __user *)pending + futex_offset, curr, pip);
+ if (pending) {
+ void __user *uaddr = futex_uaddr(pending,
+ futex_offset);
+ handle_futex_death(uaddr, curr, pip);
+ }

while (entry != (struct robust_list __user *) &head->list) {
/*
* A pending lock might already be on the list, so
* dont process it twice:
*/
- if (entry != pending)
- if (handle_futex_death((void __user *)entry + futex_offset,
- curr, pi))
+ if (entry != pending) {
+ void __user *uaddr = futex_uaddr(entry,
+ futex_offset);
+ if (handle_futex_death(uaddr, curr, pi))
return;
+ }

/*
* Fetch the next entry in the list:

--

2007-11-19 18:22:27

by Greg KH

[permalink] [raw]
Subject: [patch 01/26] SLUB: Fix memory leak by not reusing cpu_slab

2.6.22-stable review patch. If anyone has any objections, please let us know.

------------------

From: Christoph Lameter <[email protected]>

backport of 05aa345034de6ae9c77fb93f6a796013641d57d5 from Linus's tree.

SLUB: Fix memory leak by not reusing cpu_slab

Fix the memory leak that may occur when we attempt to reuse a cpu_slab
that was allocated while we reenabled interrupts in order to be able to
grow a slab cache. The per cpu freelist may contain objects and in that
situation we may overwrite the per cpu freelist pointer loosing objects.
This only occurs if we find that the concurrently allocated slab fits
our allocation needs.

If we simply always deactivate the slab then the freelist will be properly
reintegrated and the memory leak will go away.

Signed-off-by: Christoph Lameter <[email protected]>
Cc: Hugh Dickins <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
mm/slub.c | 22 +---------------------
1 file changed, 1 insertion(+), 21 deletions(-)

--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1431,28 +1431,8 @@ new_slab:
page = new_slab(s, gfpflags, node);
if (page) {
cpu = smp_processor_id();
- if (s->cpu_slab[cpu]) {
- /*
- * Someone else populated the cpu_slab while we
- * enabled interrupts, or we have gotten scheduled
- * on another cpu. The page may not be on the
- * requested node even if __GFP_THISNODE was
- * specified. So we need to recheck.
- */
- if (node == -1 ||
- page_to_nid(s->cpu_slab[cpu]) == node) {
- /*
- * Current cpuslab is acceptable and we
- * want the current one since its cache hot
- */
- discard_slab(s, page);
- page = s->cpu_slab[cpu];
- slab_lock(page);
- goto load_freelist;
- }
- /* New slab does not fit our expectations */
+ if (s->cpu_slab[cpu])
flush_slab(s, s->cpu_slab[cpu], cpu);
- }
slab_lock(page);
SetSlabFrozen(page);
s->cpu_slab[cpu] = page;

--

2007-11-19 18:22:45

by Greg KH

[permalink] [raw]
Subject: [patch 04/26] writeback: dont propagate AOP_WRITEPAGE_ACTIVATE


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Andrew Morton <[email protected]>

patch e423003028183df54f039dfda8b58c49e78c89d7 in mainline.

This is a writeback-internal marker but we're propagating it all the way back
to userspace!.

Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


---
mm/page-writeback.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -674,8 +674,10 @@ retry:

ret = (*writepage)(page, wbc, data);

- if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE))
+ if (unlikely(ret == AOP_WRITEPAGE_ACTIVATE)) {
unlock_page(page);
+ ret = 0;
+ }
if (ret || (--(wbc->nr_to_write) <= 0))
done = 1;
if (wbc->nonblocking && bdi_write_congested(bdi)) {

--

2007-11-19 18:23:07

by Greg KH

[permalink] [raw]
Subject: [patch 03/26] x86: fix TSC clock source calibration error

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Dave Johnson <[email protected]>

patch edaf420fdc122e7a42326fe39274c8b8c9b19d41 in mainline.

I ran into this problem on a system that was unable to obtain NTP sync
because the clock was running very slow (over 10000ppm slow). ntpd had
declared all of its peers 'reject' with 'peer_dist' reason.

On investigation, the tsc_khz variable was significantly incorrect
causing xtime to run slow. After a reboot tsc_khz was correct so I
did a reboot test to see how often the problem occurred:

Test was done on a 2000 Mhz Xeon system. Of 689 reboots, 8 of them
had unacceptable tsc_khz values (>500ppm):

range of tsc_khz # of boots % of boots
---------------- ---------- ----------
< 1999750 0 0.000%
1999750 - 1999800 21 3.048%
1999800 - 1999850 166 24.128%
1999850 - 1999900 241 35.029%
1999900 - 1999950 211 30.669%
1999950 - 2000000 42 6.105%
2000000 - 2000000 0 0.000%
2000050 - 2000100 0 0.000%
[...]
2000100 - 2015000 1 0.145% << BAD
2015000 - 2030000 6 0.872% << BAD
2030000 - 2045000 1 0.145% << BAD
2045000 < 0 0.000%

The worst boot was 2032.577 Mhz, over 1.5% off!

It appears that on rare occasions, mach_countup() is taking longer to
complete than necessary.

I suspect that this is caused by the CPU taking a periodic SMI
interrupt right at the end of the 30ms calibration loop. This would
cause the loop to delay while the SMI BIOS hander runs. The resulting
TSC value is beyond what it actually should be resulting in a higher
tsc_khz.

The below patch makes native_calculate_cpu_khz() take the best
(shortest duration, lowest khz) run of it's 3 calibration loops. If a
SMI goes off causing a bad result (long duration, higher khz) it will
be discarded.

With the patch applied, 300 boots of the same system produce good
results:

range of tsc_khz # of boots % of boots
---------------- ---------- ----------
< 1999750 0 0.000%
1999750 - 1999800 30 10.000%
1999800 - 1999850 166 55.333%
1999850 - 1999900 89 29.667%
1999900 - 1999950 15 5.000%
1999950 < 0 0.000%

Problem was found and tested against 2.6.18. Patch is against 2.6.22.

Signed-off-by: Dave Johnson <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
arch/i386/kernel/tsc.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

--- a/arch/i386/kernel/tsc.c
+++ b/arch/i386/kernel/tsc.c
@@ -122,7 +122,7 @@ unsigned long native_calculate_cpu_khz(v
{
unsigned long long start, end;
unsigned long count;
- u64 delta64;
+ u64 delta64 = (u64)ULLONG_MAX;
int i;
unsigned long flags;

@@ -134,6 +134,7 @@ unsigned long native_calculate_cpu_khz(v
rdtscll(start);
mach_countup(&count);
rdtscll(end);
+ delta64 = min(delta64, (end - start));
}
/*
* Error: ECTCNEVERSET
@@ -144,8 +145,6 @@ unsigned long native_calculate_cpu_khz(v
if (count <= 1)
goto err;

- delta64 = end - start;
-
/* cpu freq too fast: */
if (delta64 > (1ULL<<32))
goto err;

--

2007-11-19 18:23:31

by Greg KH

[permalink] [raw]
Subject: [patch 05/26] fix param_sysfs_builtin name length check

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jan Kiszka <[email protected]>

patch 22800a2830ec07e7cc5c837999890ac47cc7f5de in mainline.

Commit faf8c714f4508207a9c81cc94dafc76ed6680b44 caused a regression:
parameter names longer than MAX_KBUILD_MODNAME will now be rejected,
although we just need to keep the module name part that short. This patch
restores the old behaviour while still avoiding that memchr is called with
its length parameter larger than the total string length.

Signed-off-by: Jan Kiszka <[email protected]>
Cc: Dave Young <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Cc: Chuck Ebbert <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
kernel/params.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)

--- a/kernel/params.c
+++ b/kernel/params.c
@@ -591,19 +591,16 @@ static void __init param_sysfs_builtin(v

for (i=0; i < __stop___param - __start___param; i++) {
char *dot;
- size_t kplen;
+ size_t max_name_len;

kp = &__start___param[i];
- kplen = strlen(kp->name);
+ max_name_len =
+ min_t(size_t, MAX_KBUILD_MODNAME, strlen(kp->name));

- /* We do not handle args without periods. */
- if (kplen > MAX_KBUILD_MODNAME) {
- DEBUGP("kernel parameter name is too long: %s\n", kp->name);
- continue;
- }
- dot = memchr(kp->name, '.', kplen);
+ dot = memchr(kp->name, '.', max_name_len);
if (!dot) {
- DEBUGP("couldn't find period in %s\n", kp->name);
+ DEBUGP("couldn't find period in first %d characters "
+ "of %s\n", MAX_KBUILD_MODNAME, kp->name);
continue;
}
name_len = dot - kp->name;

--

2007-11-19 18:23:45

by Greg KH

[permalink] [raw]
Subject: [patch 06/26] NETFILTER: nf_conntrack_tcp: fix connection reopening

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jozsef Kadlecsik <[email protected]>

Upstream commits: 17311393 + bc34b841 merged together. Merge done by
Patrick McHardy <[email protected]>

[NETFILTER]: nf_conntrack_tcp: fix connection reopening

With your description I could reproduce the bug and actually you were
completely right: the code above is incorrect. Somehow I was able to
misread RFC1122 and mixed the roles :-(:

When a connection is >>closed actively<<, it MUST linger in
TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime).
However, it MAY >>accept<< a new SYN from the remote TCP to
reopen the connection directly from TIME-WAIT state, if it:
[...]

The fix is as follows: if the receiver initiated an active close, then the
sender may reopen the connection - otherwise try to figure out if we hold
a dead connection.

Signed-off-by: Jozsef Kadlecsik <[email protected]>
Tested-by: Krzysztof Piotr Oledzki <[email protected]>
Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


---
net/netfilter/nf_conntrack_proto_tcp.c | 38 ++++++++++++++-------------------
1 file changed, 17 insertions(+), 21 deletions(-)

--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -839,6 +839,22 @@ static int tcp_packet(struct nf_conn *co
new_state = tcp_conntracks[dir][index][old_state];

switch (new_state) {
+ case TCP_CONNTRACK_SYN_SENT:
+ if (old_state < TCP_CONNTRACK_TIME_WAIT)
+ break;
+ if ((conntrack->proto.tcp.seen[!dir].flags &
+ IP_CT_TCP_FLAG_CLOSE_INIT)
+ || (conntrack->proto.tcp.last_dir == dir
+ && conntrack->proto.tcp.last_index == TCP_RST_SET)) {
+ /* Attempt to reopen a closed/aborted connection.
+ * Delete this connection and look up again. */
+ write_unlock_bh(&tcp_lock);
+ if (del_timer(&conntrack->timeout))
+ conntrack->timeout.function((unsigned long)
+ conntrack);
+ return -NF_REPEAT;
+ }
+ /* Fall through */
case TCP_CONNTRACK_IGNORE:
/* Ignored packets:
*
@@ -888,27 +904,6 @@ static int tcp_packet(struct nf_conn *co
nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
"nf_ct_tcp: invalid state ");
return -NF_ACCEPT;
- case TCP_CONNTRACK_SYN_SENT:
- if (old_state < TCP_CONNTRACK_TIME_WAIT)
- break;
- if ((conntrack->proto.tcp.seen[dir].flags &
- IP_CT_TCP_FLAG_CLOSE_INIT)
- || after(ntohl(th->seq),
- conntrack->proto.tcp.seen[dir].td_end)) {
- /* Attempt to reopen a closed connection.
- * Delete this connection and look up again. */
- write_unlock_bh(&tcp_lock);
- if (del_timer(&conntrack->timeout))
- conntrack->timeout.function((unsigned long)
- conntrack);
- return -NF_REPEAT;
- } else {
- write_unlock_bh(&tcp_lock);
- if (LOG_INVALID(IPPROTO_TCP))
- nf_log_packet(pf, 0, skb, NULL, NULL,
- NULL, "nf_ct_tcp: invalid SYN");
- return -NF_ACCEPT;
- }
case TCP_CONNTRACK_CLOSE:
if (index == TCP_RST_SET
&& ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
@@ -941,6 +936,7 @@ static int tcp_packet(struct nf_conn *co
in_window:
/* From now on we have got in-window packets */
conntrack->proto.tcp.last_index = index;
+ conntrack->proto.tcp.last_dir = dir;

DEBUGP("tcp_conntracks: src=%u.%u.%u.%u:%hu dst=%u.%u.%u.%u:%hu "
"syn=%i ack=%i fin=%i rst=%i old=%i new=%i\n",

--

2007-11-19 18:24:04

by Greg KH

[permalink] [raw]
Subject: [patch 07/26] fix the softlockup watchdog to actually work


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Ingo Molnar <[email protected]>

patch a115d5caca1a2905ba7a32b408a6042b20179aaa in mainline.

this Xen related commit:

commit 966812dc98e6a7fcdf759cbfa0efab77500a8868
Author: Jeremy Fitzhardinge <[email protected]>
Date: Tue May 8 00:28:02 2007 -0700

Ignore stolen time in the softlockup watchdog

broke the softlockup watchdog to never report any lockups. (!)

print_timestamp defaults to 0, this makes the following condition
always true:

if (print_timestamp < (touch_timestamp + 1) ||

and we'll in essence never report soft lockups.

apparently the functionality of the soft lockup watchdog was never
actually tested with that patch applied ...

Signed-off-by: Ingo Molnar <[email protected]>
Cc: Jeremy Fitzhardinge <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
kernel/softlockup.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

--- a/kernel/softlockup.c
+++ b/kernel/softlockup.c
@@ -79,10 +79,11 @@ void softlockup_tick(void)
print_timestamp = per_cpu(print_timestamp, this_cpu);

/* report at most once a second */
- if (print_timestamp < (touch_timestamp + 1) ||
- did_panic ||
- !per_cpu(watchdog_task, this_cpu))
+ if ((print_timestamp >= touch_timestamp &&
+ print_timestamp < (touch_timestamp + 1)) ||
+ did_panic || !per_cpu(watchdog_task, this_cpu)) {
return;
+ }

/* do not print during early bootup: */
if (unlikely(system_state != SYSTEM_RUNNING)) {

--

2007-11-19 18:24:30

by Greg KH

[permalink] [raw]
Subject: [patch 08/26] Fix TEQL oops.

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Evgeniy Polyakov <[email protected]>

[PKT_SCHED]: Fix OOPS when removing devices from a teql queuing discipline

[ Upstream commit: 4f9f8311a08c0d95c70261264a2b47f2ae99683a ]

tecl_reset() is called from deactivate and qdisc is set to noop already,
but subsequent teql_xmit does not know about it and dereference private
data as teql qdisc and thus oopses.
not catch it first :)

Signed-off-by: Evgeniy Polyakov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/sched/sch_teql.c | 3 +++
1 file changed, 3 insertions(+)

--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -263,6 +263,9 @@ __teql_resolve(struct sk_buff *skb, stru
static __inline__ int
teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
{
+ if (dev->qdisc == &noop_qdisc)
+ return -ENODEV;
+
if (dev->hard_header == NULL ||
skb->dst == NULL ||
skb->dst->neighbour == NULL)

--

2007-11-19 18:24:43

by Greg KH

[permalink] [raw]
Subject: [patch 09/26] Fix netlink timeouts.

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Patrick McHardy <[email protected]>

[NETLINK]: Fix unicast timeouts

[ Upstream commit: c3d8d1e30cace31fed6186a4b8c6b1401836d89c ]

Commit ed6dcf4a in the history.git tree broke netlink_unicast timeouts
by moving the schedule_timeout() call to a new function that doesn't
propagate the remaining timeout back to the caller. This means on each
retry we start with the full timeout again.

ipc/mqueue.c seems to actually want to wait indefinitely so this
behaviour is retained.

Signed-off-by: Patrick McHardy <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
include/linux/netlink.h | 2 +-
ipc/mqueue.c | 6 ++++--
net/netlink/af_netlink.c | 10 +++++-----
3 files changed, 10 insertions(+), 8 deletions(-)

--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -173,7 +173,7 @@ extern int netlink_unregister_notifier(s
/* finegrained unicast helpers: */
struct sock *netlink_getsockbyfilp(struct file *filp);
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk);
+ long *timeo, struct sock *ssk);
void netlink_detachskb(struct sock *sk, struct sk_buff *skb);
int netlink_sendskb(struct sock *sk, struct sk_buff *skb, int protocol);

--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -1014,6 +1014,8 @@ asmlinkage long sys_mq_notify(mqd_t mqde
return -EINVAL;
}
if (notification.sigev_notify == SIGEV_THREAD) {
+ long timeo;
+
/* create the notify skb */
nc = alloc_skb(NOTIFY_COOKIE_LEN, GFP_KERNEL);
ret = -ENOMEM;
@@ -1042,8 +1044,8 @@ retry:
goto out;
}

- ret = netlink_attachskb(sock, nc, 0,
- MAX_SCHEDULE_TIMEOUT, NULL);
+ timeo = MAX_SCHEDULE_TIMEOUT;
+ ret = netlink_attachskb(sock, nc, 0, &timeo, NULL);
if (ret == 1)
goto retry;
if (ret) {
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -732,7 +732,7 @@ struct sock *netlink_getsockbyfilp(struc
* 1: repeat lookup - reference dropped while waiting for socket memory.
*/
int netlink_attachskb(struct sock *sk, struct sk_buff *skb, int nonblock,
- long timeo, struct sock *ssk)
+ long *timeo, struct sock *ssk)
{
struct netlink_sock *nlk;

@@ -741,7 +741,7 @@ int netlink_attachskb(struct sock *sk, s
if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) {
DECLARE_WAITQUEUE(wait, current);
- if (!timeo) {
+ if (!*timeo) {
if (!ssk || nlk_sk(ssk)->pid == 0)
netlink_overrun(sk);
sock_put(sk);
@@ -755,7 +755,7 @@ int netlink_attachskb(struct sock *sk, s
if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
test_bit(0, &nlk->state)) &&
!sock_flag(sk, SOCK_DEAD))
- timeo = schedule_timeout(timeo);
+ *timeo = schedule_timeout(*timeo);

__set_current_state(TASK_RUNNING);
remove_wait_queue(&nlk->wait, &wait);
@@ -763,7 +763,7 @@ int netlink_attachskb(struct sock *sk, s

if (signal_pending(current)) {
kfree_skb(skb);
- return sock_intr_errno(timeo);
+ return sock_intr_errno(*timeo);
}
return 1;
}
@@ -827,7 +827,7 @@ retry:
kfree_skb(skb);
return PTR_ERR(sk);
}
- err = netlink_attachskb(sk, skb, nonblock, timeo, ssk);
+ err = netlink_attachskb(sk, skb, nonblock, &timeo, ssk);
if (err == 1)
goto retry;
if (err)

--

2007-11-19 18:24:59

by Greg KH

[permalink] [raw]
Subject: [patch 10/26] Fix error returns in sys_socketpair()

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: David Miller <[email protected]>

patch bf3c23d171e35e6e168074a1514b0acd59cfd81a in mainline.

[NET]: Fix error reporting in sys_socketpair().

If either of the two sock_alloc_fd() calls fail, we
forget to update 'err' and thus we'll erroneously
return zero in these cases.

Based upon a report and patch from Rich Paul, and
commentary from Chuck Ebbert.

Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/socket.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- a/net/socket.c
+++ b/net/socket.c
@@ -1246,11 +1246,14 @@ asmlinkage long sys_socketpair(int famil
goto out_release_both;

fd1 = sock_alloc_fd(&newfile1);
- if (unlikely(fd1 < 0))
+ if (unlikely(fd1 < 0)) {
+ err = fd1;
goto out_release_both;
+ }

fd2 = sock_alloc_fd(&newfile2);
if (unlikely(fd2 < 0)) {
+ err = fd2;
put_filp(newfile1);
put_unused_fd(fd1);
goto out_release_both;

--

2007-11-19 18:25:41

by Greg KH

[permalink] [raw]
Subject: [patch 11/26] Fix endianness bug in U32 classifier.

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Radu Rendec <[email protected]>

changeset 543821c6f5dea5221426eaf1eac98b100249c7ac in mainline.

[PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks.

While trying to implement u32 hashes in my shaping machine I ran into
a possible bug in the u32 hash/bucket computing algorithm
(net/sched/cls_u32.c).

The problem occurs only with hash masks that extend over the octet
boundary, on little endian machines (where htonl() actually does
something).

Let's say that I would like to use 0x3fc0 as the hash mask. This means
8 contiguous "1" bits starting at b6. With such a mask, the expected
(and logical) behavior is to hash any address in, for instance,
192.168.0.0/26 in bucket 0, then any address in 192.168.0.64/26 in
bucket 1, then 192.168.0.128/26 in bucket 2 and so on.

This is exactly what would happen on a big endian machine, but on
little endian machines, what would actually happen with current
implementation is 0x3fc0 being reversed (into 0xc03f0000) by htonl()
in the userspace tool and then applied to 192.168.x.x in the u32
classifier. When shifting right by 16 bits (rank of first "1" bit in
the reversed mask) and applying the divisor mask (0xff for divisor
256), what would actually remain is 0x3f applied on the "168" octet of
the address.

One could say is this can be easily worked around by taking endianness
into account in userspace and supplying an appropriate mask (0xfc03)
that would be turned into contiguous "1" bits when reversed
(0x03fc0000). But the actual problem is the network address (inside
the packet) not being converted to host order, but used as a
host-order value when computing the bucket.

Let's say the network address is written as n31 n30 ... n0, with n0
being the least significant bit. When used directly (without any
conversion) on a little endian machine, it becomes n7 ... n0 n8 ..n15
etc in the machine's registers. Thus bits n7 and n8 would no longer be
adjacent and 192.168.64.0/26 and 192.168.128.0/26 would no longer be
consecutive.

The fix is to apply ntohl() on the hmask before computing fshift,
and in u32_hash_fold() convert the packet data to host order before
shifting down by fshift.

With helpful feedback from Jamal Hadi Salim and Jarek Poplawski.

Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/sched/cls_u32.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -107,7 +107,7 @@ static struct tc_u_common *u32_list;

static __inline__ unsigned u32_hash_fold(u32 key, struct tc_u32_sel *sel, u8 fshift)
{
- unsigned h = (key & sel->hmask)>>fshift;
+ unsigned h = ntohl(key & sel->hmask)>>fshift;

return h;
}
@@ -631,7 +631,7 @@ static int u32_change(struct tcf_proto *
n->handle = handle;
{
u8 i = 0;
- u32 mask = s->hmask;
+ u32 mask = ntohl(s->hmask);
if (mask) {
while (!(mask & 1)) {
i++;

--

2007-11-19 18:25:57

by Greg KH

[permalink] [raw]
Subject: [patch 12/26] Fix crypto_alloc_comp() error checking.

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Herbert Xu <[email protected]>

[IPSEC]: Fix crypto_alloc_comp error checking

[ Upstream commit: 4999f3621f4da622e77931b3d33ada6c7083c705 ]

The function crypto_alloc_comp returns an errno instead of NULL
to indicate error. So it needs to be tested with IS_ERR.

This is based on a patch by Vicen? Beltran Querol.

Signed-off-by: Herbert Xu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
net/ipv4/ipcomp.c | 3 ++-
net/ipv6/ipcomp6.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)

--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -17,6 +17,7 @@
#include <asm/scatterlist.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/percpu.h>
#include <linux/smp.h>
@@ -355,7 +356,7 @@ static struct crypto_comp **ipcomp_alloc
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -37,6 +37,7 @@
#include <asm/scatterlist.h>
#include <asm/semaphore.h>
#include <linux/crypto.h>
+#include <linux/err.h>
#include <linux/pfkeyv2.h>
#include <linux/random.h>
#include <linux/percpu.h>
@@ -366,7 +367,7 @@ static struct crypto_comp **ipcomp6_allo
for_each_possible_cpu(cpu) {
struct crypto_comp *tfm = crypto_alloc_comp(alg_name, 0,
CRYPTO_ALG_ASYNC);
- if (!tfm)
+ if (IS_ERR(tfm))
goto error;
*per_cpu_ptr(tfms, cpu) = tfm;
}

--

2007-11-19 18:26:28

by Greg KH

[permalink] [raw]
Subject: [patch 13/26] ALSA: hdsp - Fix zero division

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Takashi Iwai <[email protected]>

patch 2a3988f6d2c5be9d02463097775d1c66a8290527 in mainline.

Fix zero-division bug in the calculation dds offset.

Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jaroslav Kysela <[email protected]>
Cc: Maarten Bressers <[email protected]>
Cc: gentoo kernel <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
sound/pci/rme9652/hdsp.c | 3 +++
1 file changed, 3 insertions(+)

--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -3108,6 +3108,9 @@ static int hdsp_dds_offset(struct hdsp *
unsigned int dds_value = hdsp->dds_value;
int system_sample_rate = hdsp->system_sample_rate;

+ if (!dds_value)
+ return 0;
+
n = DDS_NUMERATOR;
/*
* dds_value = n / rate

--

2007-11-19 18:26:43

by Greg KH

[permalink] [raw]
Subject: [patch 14/26] ALSA: hda-codec - Add array terminator for dmic in STAC codec

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Takashi Iwai <[email protected]>

patch f6e9852ad05fa28301c83d4e2b082620de010358 in mainline.

[ALSA] hda-codec - Add array terminator for dmic in STAC codec

Reported by Jan-Marek Glogowski.

The dmic array is passed to snd_hda_parse_pin_def_config() and
should be zero-terminated.

Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
sound/pci/hda/patch_sigmatel.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)

--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -153,8 +153,9 @@ static hda_nid_t stac925x_dac_nids[1] =
0x02,
};

-static hda_nid_t stac925x_dmic_nids[1] = {
- 0x15,
+#define STAC925X_NUM_DMICS 1
+static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = {
+ 0x15, 0
};

static hda_nid_t stac922x_adc_nids[2] = {
@@ -181,8 +182,9 @@ static hda_nid_t stac9205_mux_nids[2] =
0x19, 0x1a
};

-static hda_nid_t stac9205_dmic_nids[2] = {
- 0x17, 0x18,
+#define STAC9205_NUM_DMICS 2
+static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = {
+ 0x17, 0x18, 0
};

static hda_nid_t stac9200_pin_nids[8] = {
@@ -1972,7 +1974,7 @@ static int patch_stac925x(struct hda_cod
case 0x83847633: /* STAC9202D */
case 0x83847636: /* STAC9251 */
case 0x83847637: /* STAC9251D */
- spec->num_dmics = 1;
+ spec->num_dmics = STAC925X_NUM_DMICS;
spec->dmic_nids = stac925x_dmic_nids;
break;
default:
@@ -2202,7 +2204,7 @@ static int patch_stac9205(struct hda_cod
spec->mux_nids = stac9205_mux_nids;
spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids);
spec->dmic_nids = stac9205_dmic_nids;
- spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids);
+ spec->num_dmics = STAC9205_NUM_DMICS;
spec->dmux_nid = 0x1d;

spec->init = stac9205_core_init;

--

2007-11-19 18:26:59

by Greg KH

[permalink] [raw]
Subject: [patch 16/26] hptiop: avoid buffer overflow when returning sense data


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: HighPoint Linux Team <[email protected]>

patch 0fec02c93f60fb44ba3a24a0d3e4a52521d34d3f in mainline.

avoid buffer overflow when returning sense data.

With current adapter firmware the driver is working but future firmware
updates may return sense data larger than 96 bytes, causing overflow on
scp->sense_buffer and a kernel crash.

This fix should be backported to earlier kernels.

Signed-off-by: HighPoint Linux Team <[email protected]>
Signed-off-by: James Bottomley <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/scsi/hptiop.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -377,8 +377,9 @@ static void hptiop_host_request_callback
scp->result = SAM_STAT_CHECK_CONDITION;
memset(&scp->sense_buffer,
0, sizeof(scp->sense_buffer));
- memcpy(&scp->sense_buffer,
- &req->sg_list, le32_to_cpu(req->dataxfer_length));
+ memcpy(&scp->sense_buffer, &req->sg_list,
+ min(sizeof(scp->sense_buffer),
+ le32_to_cpu(req->dataxfer_length)));
break;

default:

--

2007-11-19 18:27:30

by Greg KH

[permalink] [raw]
Subject: [patch 17/26] USB: kobil_sct: trivial backport to fix libct

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Frank Seidel <[email protected]>

Backport of a patch by Alan Cox <[email protected]> in the kernel tree
with commit 94d0f7eac77a84da2cee41b8038796891f75f09e

Original comments:
USB: kobil_sct: Rework driver

No hardware but this driver is currently totally broken so we can't make
it much worse. Remove all tbe broken invalid termios handling and replace
it with a proper set_termios method.

Frank's comments:
Without this patch the userspace libct (to access the cardreader)
segfaults.

Signed-off-by: Frank Seidel <[email protected]>
Cc: Alan Cox <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>


---
drivers/usb/serial/kobil_sct.c | 170 ++++++++++++++++-------------------------
1 file changed, 69 insertions(+), 101 deletions(-)

--- a/drivers/usb/serial/kobil_sct.c
+++ b/drivers/usb/serial/kobil_sct.c
@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_se
unsigned int set, unsigned int clear);
static void kobil_read_int_callback( struct urb *urb );
static void kobil_write_callback( struct urb *purb );
+static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old);


static struct usb_device_id id_table [] = {
@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_de
.attach = kobil_startup,
.shutdown = kobil_shutdown,
.ioctl = kobil_ioctl,
+ .set_termios = kobil_set_termios,
.tiocmget = kobil_tiocmget,
.tiocmset = kobil_tiocmset,
.open = kobil_open,
@@ -137,7 +139,6 @@ struct kobil_private {
int cur_pos; // index of the next char to send in buf
__u16 device_type;
int line_state;
- struct ktermios internal_termios;
};


@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_s

static int kobil_open (struct usb_serial_port *port, struct file *filp)
{
- int i, result = 0;
+ int result = 0;
struct kobil_private *priv;
unsigned char *transfer_buffer;
int transfer_buffer_length = 8;
@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial
port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D)

- // set up internal termios structure
- priv->internal_termios.c_iflag = port->tty->termios->c_iflag;
- priv->internal_termios.c_oflag = port->tty->termios->c_oflag;
- priv->internal_termios.c_cflag = port->tty->termios->c_cflag;
- priv->internal_termios.c_lflag = port->tty->termios->c_lflag;
-
- for (i=0; i<NCCS; i++) {
- priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i];
- }
-
// allocate memory for transfer buffer
transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL);
if (! transfer_buffer) {
@@ -358,24 +349,26 @@ static void kobil_close (struct usb_seri
}


-static void kobil_read_int_callback( struct urb *purb)
+static void kobil_read_int_callback(struct urb *urb)
{
int result;
- struct usb_serial_port *port = (struct usb_serial_port *) purb->context;
+ struct usb_serial_port *port = urb->context;
struct tty_struct *tty;
- unsigned char *data = purb->transfer_buffer;
+ unsigned char *data = urb->transfer_buffer;
+ int status = urb->status;
// char *dbg_data;

dbg("%s - port %d", __FUNCTION__, port->number);

- if (purb->status) {
- dbg("%s - port %d Read int status not zero: %d", __FUNCTION__, port->number, purb->status);
+ if (status) {
+ dbg("%s - port %d Read int status not zero: %d",
+ __FUNCTION__, port->number, status);
return;
}
-
- tty = port->tty;
- if (purb->actual_length) {
-
+
+ tty = port->tty;
+ if (urb->actual_length) {
+
// BEGIN DEBUG
/*
dbg_data = kzalloc((3 * purb->actual_length + 10) * sizeof(char), GFP_KERNEL);
@@ -390,15 +383,15 @@ static void kobil_read_int_callback( str
*/
// END DEBUG

- tty_buffer_request_room(tty, purb->actual_length);
- tty_insert_flip_string(tty, data, purb->actual_length);
+ tty_buffer_request_room(tty, urb->actual_length);
+ tty_insert_flip_string(tty, data, urb->actual_length);
tty_flip_buffer_push(tty);
}

// someone sets the dev to 0 if the close method has been called
port->interrupt_in_urb->dev = port->serial->dev;

- result = usb_submit_urb( port->interrupt_in_urb, GFP_ATOMIC );
+ result = usb_submit_urb(port->interrupt_in_urb, GFP_ATOMIC);
dbg("%s - port %d Send read URB returns: %i", __FUNCTION__, port->number, result);
}

@@ -605,102 +598,79 @@ static int kobil_tiocmset(struct usb_se
return (result < 0) ? result : 0;
}

-
-static int kobil_ioctl(struct usb_serial_port *port, struct file *file,
- unsigned int cmd, unsigned long arg)
+static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old)
{
struct kobil_private * priv;
int result;
unsigned short urb_val = 0;
- unsigned char *transfer_buffer;
- int transfer_buffer_length = 8;
- char *settings;
- void __user *user_arg = (void __user *)arg;
+ int c_cflag = port->tty->termios->c_cflag;
+ speed_t speed;
+ void * settings;

priv = usb_get_serial_port_data(port);
- if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) {
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
// This device doesn't support ioctl calls
- return 0;
- }
-
- switch (cmd) {
- case TCGETS: // 0x5401
- if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) {
- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
- return -EFAULT;
- }
- if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
- &priv->internal_termios))
- return -EFAULT;
- return 0;
-
- case TCSETS: // 0x5402
- if (!(port->tty->termios)) {
- dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number);
- return -ENOTTY;
- }
- if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) {
- dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number);
- return -EFAULT;
- }
- if (user_termios_to_kernel_termios(&priv->internal_termios,
- (struct ktermios __user *)arg))
- return -EFAULT;
-
- settings = kzalloc(50, GFP_KERNEL);
- if (! settings) {
- return -ENOBUFS;
- }
+ return;

- switch (priv->internal_termios.c_cflag & CBAUD) {
- case B1200:
+ switch (speed = tty_get_baud_rate(port->tty)) {
+ case 1200:
urb_val = SUSBCR_SBR_1200;
- strcat(settings, "1200 ");
break;
- case B9600:
+ case 9600:
default:
urb_val = SUSBCR_SBR_9600;
- strcat(settings, "9600 ");
break;
- }
+ }
+ urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;

- urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit;
- strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit ");
+ settings = kzalloc(50, GFP_KERNEL);
+ if (! settings)
+ return;

- if (priv->internal_termios.c_cflag & PARENB) {
- if (priv->internal_termios.c_cflag & PARODD) {
- urb_val |= SUSBCR_SPASB_OddParity;
- strcat(settings, "Odd Parity");
- } else {
- urb_val |= SUSBCR_SPASB_EvenParity;
- strcat(settings, "Even Parity");
- }
+ sprintf(settings, "%d ", speed);
+
+ if (c_cflag & PARENB) {
+ if (c_cflag & PARODD) {
+ urb_val |= SUSBCR_SPASB_OddParity;
+ strcat(settings, "Odd Parity");
} else {
- urb_val |= SUSBCR_SPASB_NoParity;
- strcat(settings, "No Parity");
+ urb_val |= SUSBCR_SPASB_EvenParity;
+ strcat(settings, "Even Parity");
}
- dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings );
+ } else {
+ urb_val |= SUSBCR_SPASB_NoParity;
+ strcat(settings, "No Parity");
+ }

- result = usb_control_msg( port->serial->dev,
- usb_rcvctrlpipe(port->serial->dev, 0 ),
- SUSBCRequest_SetBaudRateParityAndStopBits,
- USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
- urb_val,
- 0,
- settings,
- 0,
- KOBIL_TIMEOUT
- );
+ result = usb_control_msg( port->serial->dev,
+ usb_rcvctrlpipe(port->serial->dev, 0 ),
+ SUSBCRequest_SetBaudRateParityAndStopBits,
+ USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ urb_val,
+ 0,
+ settings,
+ 0,
+ KOBIL_TIMEOUT
+ );
+ kfree(settings);
+}

- dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result);
- kfree(settings);
+static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg)
+{
+ struct kobil_private * priv = usb_get_serial_port_data(port);
+ unsigned char *transfer_buffer;
+ int transfer_buffer_length = 8;
+ int result;
+
+ if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)
+ // This device doesn't support ioctl calls
return 0;

+ switch (cmd) {
case TCFLSH: // 0x540B
transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL);
- if (! transfer_buffer) {
+ if (! transfer_buffer)
return -ENOBUFS;
- }

result = usb_control_msg( port->serial->dev,
usb_rcvctrlpipe(port->serial->dev, 0 ),
@@ -714,15 +684,13 @@ static int kobil_ioctl(struct usb_seria
);

dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result);
-
kfree(transfer_buffer);
- return ((result < 0) ? -EFAULT : 0);
-
+ return (result < 0) ? -EFAULT : 0;
+ default:
+ return -ENOIOCTLCMD;
}
- return -ENOIOCTLCMD;
}

-
static int __init kobil_init (void)
{
int retval;

--

2007-11-19 18:27:46

by Greg KH

[permalink] [raw]
Subject: [patch 18/26] USB: usbserial - fix potential deadlock between write() and IRQ

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jiri Kosina <[email protected]>

patch acd2a847e7fee7df11817f67dba75a2802793e5d in mainline.

USB: usbserial - fix potential deadlock between write() and IRQ

usb_serial_generic_write() doesn't disable interrupts when taking port->lock,
and could therefore deadlock with usb_serial_generic_read_bulk_callback()
being called from interrupt, taking the same lock. Fix it.

Signed-off-by: Jiri Kosina <[email protected]>
Acked-by: Larry Finger <[email protected]>
Cc: Marcin Slusarz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/usb/serial/generic.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)

--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -190,14 +190,15 @@ int usb_serial_generic_write(struct usb_

/* only do something if we have a bulk out endpoint */
if (serial->num_bulk_out) {
- spin_lock_bh(&port->lock);
+ unsigned long flags;
+ spin_lock_irqsave(&port->lock, flags);
if (port->write_urb_busy) {
- spin_unlock_bh(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);
dbg("%s - already writing", __FUNCTION__);
return 0;
}
port->write_urb_busy = 1;
- spin_unlock_bh(&port->lock);
+ spin_unlock_irqrestore(&port->lock, flags);

count = (count > port->bulk_out_size) ? port->bulk_out_size : count;


--

2007-11-19 18:28:05

by Greg KH

[permalink] [raw]
Subject: [patch 19/26] USB: mutual exclusion for EHCI init and port resets


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Alan Stern <[email protected]>

patch 32fe01985aa2cb2562f6fc171e526e279abe10db in mainline.

This patch (as999) fixes a problem that sometimes shows up when host
controller driver modules are loaded in the wrong order. If ehci-hcd
happens to initialize an EHCI controller while the companion OHCI or
UHCI controller is in the middle of a port reset, the reset can fail
and the companion may get very confused. The patch adds an
rw-semaphore and uses it to keep EHCI initialization and port resets
mutually exclusive.

Signed-off-by: Alan Stern <[email protected]>
Acked-by: David Brownell <[email protected]>
Cc: David Miller <[email protected]>
Cc: Dely L Sy <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/usb/core/hcd.h | 8 +++++++-
drivers/usb/core/hub.c | 15 ++++++++++++++-
drivers/usb/host/ehci-hcd.c | 8 ++++++++
3 files changed, 29 insertions(+), 2 deletions(-)

--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -19,6 +19,8 @@

#ifdef __KERNEL__

+#include <linux/rwsem.h>
+
/* This file contains declarations of usbcore internals that are mostly
* used or exposed by Host Controller Drivers.
*/
@@ -464,5 +466,9 @@ static inline void usbmon_urb_complete(s
: (in_interrupt () ? "in_interrupt" : "can sleep"))


-#endif /* __KERNEL__ */
+/* This rwsem is for use only by the hub driver and ehci-hcd.
+ * Nobody else should touch it.
+ */
+extern struct rw_semaphore ehci_cf_port_reset_rwsem;

+#endif /* __KERNEL__ */
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -117,6 +117,12 @@ MODULE_PARM_DESC(use_both_schemes,
"try the other device initialization scheme if the "
"first one fails");

+/* Mutual exclusion for EHCI CF initialization. This interferes with
+ * port reset on some companion controllers.
+ */
+DECLARE_RWSEM(ehci_cf_port_reset_rwsem);
+EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
+

static inline char *portspeed(int portstatus)
{
@@ -1513,6 +1519,11 @@ static int hub_port_reset(struct usb_hub
{
int i, status;

+ /* Block EHCI CF initialization during the port reset.
+ * Some companion controllers don't like it when they mix.
+ */
+ down_read(&ehci_cf_port_reset_rwsem);
+
/* Reset the port */
for (i = 0; i < PORT_RESET_TRIES; i++) {
status = set_port_feature(hub->hdev,
@@ -1543,7 +1554,7 @@ static int hub_port_reset(struct usb_hub
usb_set_device_state(udev, status
? USB_STATE_NOTATTACHED
: USB_STATE_DEFAULT);
- return status;
+ goto done;
}

dev_dbg (hub->intfdev,
@@ -1556,6 +1567,8 @@ static int hub_port_reset(struct usb_hub
"Cannot enable port %i. Maybe the USB cable is bad?\n",
port1);

+ done:
+ up_read(&ehci_cf_port_reset_rwsem);
return status;
}

--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -566,10 +566,18 @@ static int ehci_run (struct usb_hcd *hcd
* are explicitly handed to companion controller(s), so no TT is
* involved with the root hub. (Except where one is integrated,
* and there's no companion controller unless maybe for USB OTG.)
+ *
+ * Turning on the CF flag will transfer ownership of all ports
+ * from the companions to the EHCI controller. If any of the
+ * companions are in the middle of a port reset at the time, it
+ * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
+ * guarantees that no resets are in progress.
*/
+ down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+ up_write(&ehci_cf_port_reset_rwsem);

temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));
ehci_info (ehci,

--

2007-11-19 18:28:29

by Greg KH

[permalink] [raw]
Subject: [patch 20/26] i4l: Fix random hard freeze with AVM c4 card


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Karsten Keil <[email protected]>

patch 1ccfd63367c1a6aaf8b33943f18856dde85f2f0b in mainline.

The patch
- Includes the call to capilib_data_b3_req in the spinlock. This routine
in turn calls the offending mq_enqueue routine that triggered the
freeze if not locked. This should also fix other indicators of
incosistent capilib_msgidqueue list, that trigger messages like:
Oct 5 03:05:57 BERL0 kernel: kcapi: msgid 3019 ncci 0x30301 not on queue
that we saw several times a day (usually several in a row).
- Fixes all occurrences of c4_dispatch_tx to be called with active
spinlock, there were some instances where no lock was active. Mostly
these are in very infrequently called routines, so the additional
performance penalty is minimal.

Signed-off-by: Karsten Keil <[email protected]>
Signed-off-by: Rainer Brestan <[email protected]>
Signed-off-by: Ralf Schlatterbeck <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/isdn/hardware/avm/c4.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)

--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -727,6 +727,7 @@ static void c4_send_init(avmcard *card)
{
struct sk_buff *skb;
void *p;
+ unsigned long flags;

skb = alloc_skb(15, GFP_ATOMIC);
if (!skb) {
@@ -744,12 +745,15 @@ static void c4_send_init(avmcard *card)
skb_put(skb, (u8 *)p - (u8 *)skb->data);

skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
}

static int queue_sendconfigword(avmcard *card, u32 val)
{
struct sk_buff *skb;
+ unsigned long flags;
void *p;

skb = alloc_skb(3+4, GFP_ATOMIC);
@@ -766,7 +770,9 @@ static int queue_sendconfigword(avmcard
skb_put(skb, (u8 *)p - (u8 *)skb->data);

skb_queue_tail(&card->dma->send_queue, skb);
+ spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
+ spin_unlock_irqrestore(&card->lock, flags);
return 0;
}

@@ -986,7 +992,9 @@ static void c4_release_appl(struct capi_
struct sk_buff *skb;
void *p;

+ spin_lock_irqsave(&card->lock, flags);
capilib_release_appl(&cinfo->ncci_head, appl);
+ spin_unlock_irqrestore(&card->lock, flags);

if (ctrl->cnr == card->cardnr) {
skb = alloc_skb(7, GFP_ATOMIC);
@@ -1019,7 +1027,8 @@ static u16 c4_send_message(struct capi_c
u16 retval = CAPI_NOERROR;
unsigned long flags;

- if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
+ spin_lock_irqsave(&card->lock, flags);
+ if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
@@ -1027,10 +1036,9 @@ static u16 c4_send_message(struct capi_c
}
if (retval == CAPI_NOERROR) {
skb_queue_tail(&card->dma->send_queue, skb);
- spin_lock_irqsave(&card->lock, flags);
c4_dispatch_tx(card);
- spin_unlock_irqrestore(&card->lock, flags);
}
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
}


--

2007-11-19 18:28:43

by Greg KH

[permalink] [raw]
Subject: [patch 21/26] i4l: fix random freezes with AVM B1 drivers


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Karsten Keil <[email protected]>

patch 9713d9e650045f7f2afd81d58a068827be306993 in mainline.

This fix the same issue which was debbuged for the C4 controller for the B1
versions.

The capilib_ function modify or traverse a linked list without locking.

This patch extends the existing locking to the calls of these function to
prevent access to a list which is in the middle of a modification.

Signed-off-by: Karsten Keil <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/isdn/hardware/avm/b1.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)

--- a/drivers/isdn/hardware/avm/b1.c
+++ b/drivers/isdn/hardware/avm/b1.c
@@ -321,12 +321,15 @@ void b1_reset_ctr(struct capi_ctr *ctrl)
avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
avmcard *card = cinfo->card;
unsigned int port = card->port;
+ unsigned long flags;

b1_reset(port);
b1_reset(port);

memset(cinfo->version, 0, sizeof(cinfo->version));
+ spin_lock_irqsave(&card->lock, flags);
capilib_release(&cinfo->ncci_head);
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_reseted(ctrl);
}

@@ -361,9 +364,8 @@ void b1_release_appl(struct capi_ctr *ct
unsigned int port = card->port;
unsigned long flags;

- capilib_release_appl(&cinfo->ncci_head, appl);
-
spin_lock_irqsave(&card->lock, flags);
+ capilib_release_appl(&cinfo->ncci_head, appl);
b1_put_byte(port, SEND_RELEASE);
b1_put_word(port, appl);
spin_unlock_irqrestore(&card->lock, flags);
@@ -380,27 +382,27 @@ u16 b1_send_message(struct capi_ctr *ctr
u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
u16 dlen, retval;

+ spin_lock_irqsave(&card->lock, flags);
if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
retval = capilib_data_b3_req(&cinfo->ncci_head,
CAPIMSG_APPID(skb->data),
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
- if (retval != CAPI_NOERROR)
+ if (retval != CAPI_NOERROR) {
+ spin_unlock_irqrestore(&card->lock, flags);
return retval;
+ }

dlen = CAPIMSG_DATALEN(skb->data);

- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_DATA_B3_REQ);
b1_put_slice(port, skb->data, len);
b1_put_slice(port, skb->data + len, dlen);
- spin_unlock_irqrestore(&card->lock, flags);
} else {
- spin_lock_irqsave(&card->lock, flags);
b1_put_byte(port, SEND_MESSAGE);
b1_put_slice(port, skb->data, len);
- spin_unlock_irqrestore(&card->lock, flags);
}
+ spin_unlock_irqrestore(&card->lock, flags);

dev_kfree_skb_any(skb);
return CAPI_NOERROR;
@@ -534,17 +536,17 @@ irqreturn_t b1_interrupt(int interrupt,

ApplId = (unsigned) b1_get_word(card->port);
MsgLen = b1_get_slice(card->port, card->msgbuf);
- spin_unlock_irqrestore(&card->lock, flags);
if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
printk(KERN_ERR "%s: incoming packet dropped\n",
card->name);
+ spin_unlock_irqrestore(&card->lock, flags);
} else {
memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF)
capilib_data_b3_conf(&cinfo->ncci_head, ApplId,
CAPIMSG_NCCI(skb->data),
CAPIMSG_MSGID(skb->data));
-
+ spin_unlock_irqrestore(&card->lock, flags);
capi_ctr_handle_message(ctrl, ApplId, skb);
}
break;
@@ -554,21 +556,17 @@ irqreturn_t b1_interrupt(int interrupt,
ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
WindowSize = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;

case RECEIVE_FREE_NCCI:

ApplId = b1_get_word(card->port);
NCCI = b1_get_word(card->port);
- spin_unlock_irqrestore(&card->lock, flags);
-
if (NCCI != 0xffffffff)
capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI);
-
+ spin_unlock_irqrestore(&card->lock, flags);
break;

case RECEIVE_START:

--

2007-11-19 18:28:59

by Greg KH

[permalink] [raw]
Subject: [patch 22/26] ide: fix serverworks.c UDMA regression

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Tony Battersby <[email protected]>

patch 0c824b51b338c808de650b440ba5f9f4a725f7fc in mainline.

The patch described by the following excerpt from ChangeLog-2.6.22 makes
it impossible to use UDMA on a Tyan S2707 motherboard (SvrWks CSB5):

commit 2d5eaa6dd744a641e75503232a01f52d0768884c
Author: Bartlomiej Zolnierkiewicz <[email protected]>
Date: Thu May 10 00:01:08 2007 +0200

ide: rework the code for selecting the best DMA transfer mode (v3)

...

This one-line patch against 2.6.23 fixes the problem.

Signed-off-by: Tony Battersby <[email protected]>
Signed-off-by: Bartlomiej Zolnierkiewicz <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/ide/pci/serverworks.c | 1 +
1 file changed, 1 insertion(+)

--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -101,6 +101,7 @@ static u8 svwks_udma_filter(ide_drive_t
mode = 2;

switch(mode) {
+ case 3: mask = 0x3f; break;
case 2: mask = 0x1f; break;
case 1: mask = 0x07; break;
default: mask = 0x00; break;

--

2007-11-19 18:29:24

by Greg KH

[permalink] [raw]
Subject: [patch 23/26] ocfs2: fix write() performance regression


2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Mark Fasheh <[email protected]>

ocfs2: fix write() performance regression

patch 4e9563fd55ff4479f2b118d0757d121dd0cfc39c in mainline.

On file systems which don't support sparse files, Ocfs2_map_page_blocks()
was reading blocks on appending writes. This caused write performance to
suffer dramatically. Fix this by detecting an appending write on a nonsparse
fs and skipping the read.

Signed-off-by: Mark Fasheh <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
fs/ocfs2/aops.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)

--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -661,6 +661,27 @@ static void ocfs2_clear_page_regions(str
}

/*
+ * Nonsparse file systems fully allocate before we get to the write
+ * code. This prevents ocfs2_write() from tagging the write as an
+ * allocating one, which means ocfs2_map_page_blocks() might try to
+ * read-in the blocks at the tail of our file. Avoid reading them by
+ * testing i_size against each block offset.
+ */
+static int ocfs2_should_read_blk(struct inode *inode, struct page *page,
+ unsigned int block_start)
+{
+ u64 offset = page_offset(page) + block_start;
+
+ if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
+ return 1;
+
+ if (i_size_read(inode) > offset)
+ return 1;
+
+ return 0;
+}
+
+/*
* Some of this taken from block_prepare_write(). We already have our
* mapping by now though, and the entire write will be allocating or
* it won't, so not much need to use BH_New.
@@ -711,7 +732,8 @@ int ocfs2_map_page_blocks(struct page *p
if (!buffer_uptodate(bh))
set_buffer_uptodate(bh);
} else if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
- (block_start < from || block_end > to)) {
+ ocfs2_should_read_blk(inode, page, block_start) &&
+ (block_start < from || block_end > to)) {
ll_rw_block(READ, 1, &bh);
*wait_bh++=bh;
}

--

2007-11-19 18:29:40

by Greg KH

[permalink] [raw]
Subject: [patch 15/26] forcedeth msi bugfix

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Manfred Spraul <[email protected]>

patch a7475906bc496456ded9e4b062f94067fb93057a in mainline.

pci_enable_msi() replaces the INTx irq number in pci_dev->irq with the
new MSI irq number.
The forcedeth driver did not update the copy in netdevice->irq and
parts of the driver used the stale copy.
See bugzilla.kernel.org, bug 9047.

The patch
- updates netdevice->irq
- replaces all accesses to netdevice->irq with pci_dev->irq.

The patch is against 2.6.23.1. IMHO suitable for both 2.6.23 and 2.6.24

Signed-off-by: Manfred Spraul <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/net/forcedeth.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)

--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -987,7 +987,7 @@ static void nv_enable_irq(struct net_dev
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1003,7 +1003,7 @@ static void nv_disable_irq(struct net_de
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
@@ -1600,7 +1600,7 @@ static void nv_do_rx_refill(unsigned lon
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq(dev->irq);
+ disable_irq(np->pci_dev->irq);
} else {
disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -1618,7 +1618,7 @@ static void nv_do_rx_refill(unsigned lon
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq(dev->irq);
+ enable_irq(np->pci_dev->irq);
} else {
enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
}
@@ -3556,10 +3556,12 @@ static int nv_request_irq(struct net_dev
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
np->msi_flags |= NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
if (request_irq(np->pci_dev->irq, handler, IRQF_SHARED, dev->name, dev) != 0) {
printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
pci_disable_msi(np->pci_dev);
np->msi_flags &= ~NV_MSI_ENABLED;
+ dev->irq = np->pci_dev->irq;
goto out_err;
}

@@ -3622,7 +3624,7 @@ static void nv_do_nic_poll(unsigned long
if (np->msi_flags & NV_MSI_X_ENABLED)
disable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- disable_irq_lockdep(dev->irq);
+ disable_irq_lockdep(np->pci_dev->irq);
mask = np->irqmask;
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -3640,6 +3642,8 @@ static void nv_do_nic_poll(unsigned long
}
np->nic_poll_irq = 0;

+ /* disable_irq() contains synchronize_irq, thus no irq handler can run now */
+
if (np->recover_error) {
np->recover_error = 0;
printk(KERN_INFO "forcedeth: MAC in recoverable error state\n");
@@ -3676,7 +3680,6 @@ static void nv_do_nic_poll(unsigned long
}
}

- /* FIXME: Do we need synchronize_irq(dev->irq) here? */

writel(mask, base + NvRegIrqMask);
pci_push(base);
@@ -3689,7 +3692,7 @@ static void nv_do_nic_poll(unsigned long
if (np->msi_flags & NV_MSI_X_ENABLED)
enable_irq_lockdep(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
else
- enable_irq_lockdep(dev->irq);
+ enable_irq_lockdep(np->pci_dev->irq);
} else {
if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
nv_nic_irq_rx(0, dev);
@@ -4943,7 +4946,7 @@ static int nv_close(struct net_device *d
np->in_shutdown = 1;
spin_unlock_irq(&np->lock);
netif_poll_disable(dev);
- synchronize_irq(dev->irq);
+ synchronize_irq(np->pci_dev->irq);

del_timer_sync(&np->oom_kick);
del_timer_sync(&np->nic_poll);

--

2007-11-19 18:29:57

by Greg KH

[permalink] [raw]
Subject: [patch 24/26] i2c-pasemi: Fix NACK detection

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jean Delvare <[email protected]>

patch be8a1f7cd4501c3b4b32543577a33aee6d2193ac in mainline.

Turns out we don't actually check the status to see if there was a
device out there to talk to, just if we had a timeout when doing so.

Add the proper check, so we don't falsly think there are devices
on the bus that are not there, etc.

Signed-off-by: Olof Johansson <[email protected]>
Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/i2c/busses/i2c-pasemi.c | 5 +++++
1 file changed, 5 insertions(+)

--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -51,6 +51,7 @@ struct pasemi_smbus {
#define MRXFIFO_DATA_M 0x000000ff

#define SMSTA_XEN 0x08000000
+#define SMSTA_MTN 0x00200000

#define CTL_MRR 0x00000400
#define CTL_MTR 0x00000200
@@ -98,6 +99,10 @@ static unsigned int pasemi_smb_waitready
status = reg_read(smbus, REG_SMSTA);
}

+ /* Got NACK? */
+ if (status & SMSTA_MTN)
+ return -ENXIO;
+
if (timeout < 0) {
dev_warn(&smbus->dev->dev, "Timeout, status 0x%08x\n", status);
reg_write(smbus, REG_SMSTA, status);

--

2007-11-19 18:30:31

by Greg KH

[permalink] [raw]
Subject: [patch 25/26] i2c/eeprom: Hide Sony Vaio serial numbers

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jean Delvare <[email protected]>

patch 0f2cbd38aa377e30df3b7602abed69464d1970aa in mainline.

The sysfs interface to DMI data takes care to not make the system
serial number and UUID world-readable, presumably due to privacy
concerns. For consistency, we should not let the eeprom driver
export these same strings to the world on Sony Vaio laptops.
Instead, only make them readable by root, as we already do for BIOS
passwords.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/i2c/chips/eeprom.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)

--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -125,13 +125,20 @@ static ssize_t eeprom_read(struct kobjec
for (slice = off >> 5; slice <= (off + count - 1) >> 5; slice++)
eeprom_update_client(client, slice);

- /* Hide Vaio security settings to regular users (16 first bytes) */
- if (data->nature == VAIO && off < 16 && !capable(CAP_SYS_ADMIN)) {
- size_t in_row1 = 16 - off;
- in_row1 = min(in_row1, count);
- memset(buf, 0, in_row1);
- if (count - in_row1 > 0)
- memcpy(buf + in_row1, &data->data[16], count - in_row1);
+ /* Hide Vaio private settings to regular users:
+ - BIOS passwords: bytes 0x00 to 0x0f
+ - UUID: bytes 0x10 to 0x1f
+ - Serial number: 0xc0 to 0xdf */
+ if (data->nature == VAIO && !capable(CAP_SYS_ADMIN)) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ if ((off + i <= 0x1f) ||
+ (off + i >= 0xc0 && off + i <= 0xdf))
+ buf[i] = 0;
+ else
+ buf[i] = data->data[off + i];
+ }
} else {
memcpy(buf, &data->data[off], count);
}
@@ -202,7 +209,7 @@ static int eeprom_detect(struct i2c_adap
&& i2c_smbus_read_byte(new_client) == 'G'
&& i2c_smbus_read_byte(new_client) == '-') {
dev_info(&new_client->dev, "Vaio EEPROM detected, "
- "enabling password protection\n");
+ "enabling privacy protection\n");
data->nature = VAIO;
}
}

--

2007-11-19 18:30:50

by Greg KH

[permalink] [raw]
Subject: [patch 26/26] i2c/eeprom: Recognize VGN as a valid Sony Vaio name prefix

2.6.22-stable review patch. If anyone has any objections, please let us
know.

------------------
From: Jean Delvare <[email protected]>

patch 8b925a3dd8a4d7451092cb9aa11da727ba69e0f0 in mainline.

Recent (i.e. 2005 and later) Sony Vaio laptops have names beginning
with VGN rather than PCG. Update the eeprom driver so that it
recognizes these.

Why this matters: the eeprom driver hides private data from the
EEPROMs it recognizes as Vaio EEPROMs (passwords, serial number...) so
if the driver fails to recognize a Vaio EEPROM as such, the private
data is exposed to the world.

Signed-off-by: Jean Delvare <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
drivers/i2c/chips/eeprom.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)

--- a/drivers/i2c/chips/eeprom.c
+++ b/drivers/i2c/chips/eeprom.c
@@ -202,12 +202,16 @@ static int eeprom_detect(struct i2c_adap
goto exit_kfree;

/* Detect the Vaio nature of EEPROMs.
- We use the "PCG-" prefix as the signature. */
+ We use the "PCG-" or "VGN-" prefix as the signature. */
if (address == 0x57) {
- if (i2c_smbus_read_byte_data(new_client, 0x80) == 'P'
- && i2c_smbus_read_byte(new_client) == 'C'
- && i2c_smbus_read_byte(new_client) == 'G'
- && i2c_smbus_read_byte(new_client) == '-') {
+ char name[4];
+
+ name[0] = i2c_smbus_read_byte_data(new_client, 0x80);
+ name[1] = i2c_smbus_read_byte(new_client);
+ name[2] = i2c_smbus_read_byte(new_client);
+ name[3] = i2c_smbus_read_byte(new_client);
+
+ if (!memcmp(name, "PCG-", 4) || !memcmp(name, "VGN-", 4)) {
dev_info(&new_client->dev, "Vaio EEPROM detected, "
"enabling privacy protection\n");
data->nature = VAIO;

--

2007-11-19 18:31:12

by Greg KH

[permalink] [raw]
Subject: Re: [patch 00/26] 2.6.22-stable review

On Mon, Nov 19, 2007 at 10:17:46AM -0800, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 2.6.22.14 release.
> There are 26 patches in this series, all will be posted as a response to
> this one. If anyone has any issues with these being applied, please let
> us know. If anyone is a maintainer of the proper subsystem, and wants
> to add a Signed-off-by: line to the patch, please respond with it.

Full patch can be found at:
kernel.org/pub/linux/kernel/v2.6/stable-review-patch-2.6.22.14-rc1.gz

and the diffstat is below.

thanks,

greg k-h

------------

Makefile | 2
arch/i386/kernel/tsc.c | 5
drivers/i2c/busses/i2c-pasemi.c | 5
drivers/i2c/chips/eeprom.c | 37 ++++---
drivers/ide/pci/serverworks.c | 1
drivers/isdn/hardware/avm/b1.c | 28 ++---
drivers/isdn/hardware/avm/c4.c | 14 ++
drivers/net/forcedeth.c | 19 ++-
drivers/scsi/hptiop.c | 5
drivers/usb/core/hcd.h | 8 +
drivers/usb/core/hub.c | 15 ++
drivers/usb/host/ehci-hcd.c | 8 +
drivers/usb/serial/generic.c | 7 -
drivers/usb/serial/kobil_sct.c | 170 +++++++++++++--------------------
fs/ocfs2/aops.c | 24 ++++
include/linux/netlink.h | 2
ipc/mqueue.c | 6 -
kernel/futex_compat.c | 24 +++-
kernel/params.c | 15 +-
kernel/softlockup.c | 7 -
mm/page-writeback.c | 4
mm/slub.c | 22 ----
net/ipv4/ipcomp.c | 3
net/ipv6/ipcomp6.c | 3
net/netfilter/nf_conntrack_proto_tcp.c | 38 +++----
net/netlink/af_netlink.c | 10 -
net/sched/cls_u32.c | 4
net/sched/sch_teql.c | 3
net/socket.c | 5
sound/pci/hda/patch_sigmatel.c | 14 +-
sound/pci/rme9652/hdsp.c | 3
31 files changed, 280 insertions(+), 231 deletions(-)

2007-11-19 18:38:48

by Matthew Wilcox

[permalink] [raw]
Subject: Re: [patch 16/26] hptiop: avoid buffer overflow when returning sense data

On Mon, Nov 19, 2007 at 10:19:12AM -0800, Greg Kroah-Hartman wrote:
>
> 2.6.22-stable review patch. If anyone has any objections, please let us
> know.

Makes sense to backport this.

Acked-by: Matthew Wilcox <[email protected]>

--
Intel are signing my paycheques ... these opinions are still mine
"Bill, look, we understand that you're interested in selling us this
operating system, but compare it to ours. We can't possibly take such
a retrograde step."

2007-11-19 18:41:40

by David Brownell

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

Still needs the following update, IMO ...

====== CUT HERE
A recent patch added software synchronization during EHCI startup,
so ports aren't switched away from the companion controllers after
resets have started. This patch adds a short delay letting hardware
get a chance to finish that port switching before any new resets begin.

That is, both sides of that hardware race window need to be closed.

Signed-off-by: David Brownell <[email protected]>
---
drivers/usb/host/ehci-hcd.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

--- g26.orig/drivers/usb/host/ehci-hcd.c 2007-11-13 16:07:12.000000000 -0800
+++ g26/drivers/usb/host/ehci-hcd.c 2007-11-13 16:13:01.000000000 -0800
@@ -594,12 +594,15 @@ static int ehci_run (struct usb_hcd *hcd
* from the companions to the EHCI controller. If any of the
* companions are in the middle of a port reset at the time, it
* could cause trouble. Write-locking ehci_cf_port_reset_rwsem
- * guarantees that no resets are in progress.
+ * guarantees that no resets are in progress. After we set CF,
+ * a short delay lets the hardware catch up; new resets shouldn't
+ * start before the port switching actions complete.
*/
down_write(&ehci_cf_port_reset_rwsem);
hcd->state = HC_STATE_RUNNING;
ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
+ msleep(5);
up_write(&ehci_cf_port_reset_rwsem);

temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));

2007-11-19 18:47:28

by Greg KH

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

On Mon, Nov 19, 2007 at 10:41:28AM -0800, David Brownell wrote:
> Still needs the following update, IMO ...

Yes, but that patch isn't in Linus's tree yet, so I can't add it to the
-stable trees.

It's in my queue to send to Linus, but that's not going to happen until
next week at the earliest...

thanks,

greg k-h

2007-11-19 19:03:46

by Ingo Molnar

[permalink] [raw]
Subject: Re: [patch 07/26] fix the softlockup watchdog to actually work


* Greg Kroah-Hartman <[email protected]> wrote:

> 2.6.22-stable review patch. If anyone has any objections, please let
> us know.

we shouldnt do this for 2.6.22 - it has no proper cpu_clock() facility
like .23 or .24. So lets leave this alone.

Ingo

2007-11-19 19:05:04

by Alan Stern

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

On Mon, 19 Nov 2007, David Brownell wrote:

> Still needs the following update, IMO ...
>
> ====== CUT HERE
> A recent patch added software synchronization during EHCI startup,
> so ports aren't switched away from the companion controllers after
> resets have started. This patch adds a short delay letting hardware
> get a chance to finish that port switching before any new resets begin.
>
> That is, both sides of that hardware race window need to be closed.
>
> Signed-off-by: David Brownell <[email protected]>
> ---
> drivers/usb/host/ehci-hcd.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> --- g26.orig/drivers/usb/host/ehci-hcd.c 2007-11-13 16:07:12.000000000 -0800
> +++ g26/drivers/usb/host/ehci-hcd.c 2007-11-13 16:13:01.000000000 -0800
> @@ -594,12 +594,15 @@ static int ehci_run (struct usb_hcd *hcd
> * from the companions to the EHCI controller. If any of the
> * companions are in the middle of a port reset at the time, it
> * could cause trouble. Write-locking ehci_cf_port_reset_rwsem
> - * guarantees that no resets are in progress.
> + * guarantees that no resets are in progress. After we set CF,
> + * a short delay lets the hardware catch up; new resets shouldn't
> + * start before the port switching actions complete.
> */
> down_write(&ehci_cf_port_reset_rwsem);
> hcd->state = HC_STATE_RUNNING;
> ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag);
> ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */
> + msleep(5);
> up_write(&ehci_cf_port_reset_rwsem);
>
> temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase));

This addition certainly won't hurt. Did we ever get any feedback as to
whether it actually helped?

Alan Stern

2007-11-19 19:28:38

by Hugh Dickins

[permalink] [raw]
Subject: Re: [patch 04/26] writeback: dont propagate AOP_WRITEPAGE_ACTIVATE

On Mon, 19 Nov 2007, Greg Kroah-Hartman wrote:
>
> 2.6.22-stable review patch. If anyone has any objections, please let us
> know.
>
> ------------------
> From: Andrew Morton <[email protected]>
>
> patch e423003028183df54f039dfda8b58c49e78c89d7 in mainline.
>
> This is a writeback-internal marker but we're propagating it all the way back
> to userspace!.
>
> Signed-off-by: Andrew Morton <[email protected]>
> Signed-off-by: Linus Torvalds <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>

It's fine by me that this should go into 2.6.22-stable, but then please
also put in this related patch from 2.6.23-stable: it's arguable whether
either are strictly needed (they were originally provoked by unionfs, in
Ubuntu but not mainline), but more helpful to include than exclude them.

Thanks,
Hugh


Subject: [patch 12/13] fix tmpfs BUG and AOP_WRITEPAGE_ACTIVATE

-stable review patch. If anyone has any objections, please let us know.

------------------

From: Hugh Dickins <[email protected]>

patch 487e9bf25cbae11b131d6a14bdbb3a6a77380837 in mainline.

It's possible to provoke unionfs (not yet in mainline, though in mm and
some distros) to hit shmem_writepage's BUG_ON(page_mapped(page)). I expect
it's possible to provoke the 2.6.23 ecryptfs in the same way (but the
2.6.24 ecryptfs no longer calls lower level's ->writepage).

This came to light with the recent find that AOP_WRITEPAGE_ACTIVATE could
leak from tmpfs via write_cache_pages and unionfs to userspace. There's
already a fix (e423003028183df54f039dfda8b58c49e78c89d7 - writeback: don't
propagate AOP_WRITEPAGE_ACTIVATE) in the tree for that, and it's okay so
far as it goes; but insufficient because it doesn't address the underlying
issue, that shmem_writepage expects to be called only by vmscan (relying on
backing_dev_info capabilities to prevent the normal writeback path from
ever approaching it).

That's an increasingly fragile assumption, and ramdisk_writepage (the other
source of AOP_WRITEPAGE_ACTIVATEs) is already careful to check
wbc->for_reclaim before returning it. Make the same check in
shmem_writepage, thereby sidestepping the page_mapped BUG also.

Signed-off-by: Hugh Dickins <[email protected]>
Cc: Erez Zadok <[email protected]>
Reviewed-by: Pekka Enberg <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>

---
mm/shmem.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)

--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -916,6 +916,21 @@ static int shmem_writepage(struct page *
struct inode *inode;

BUG_ON(!PageLocked(page));
+ /*
+ * shmem_backing_dev_info's capabilities prevent regular writeback or
+ * sync from ever calling shmem_writepage; but a stacking filesystem
+ * may use the ->writepage of its underlying filesystem, in which case
+ * we want to do nothing when that underlying filesystem is tmpfs
+ * (writing out to swap is useful as a response to memory pressure, but
+ * of no use to stabilize the data) - just redirty the page, unlock it
+ * and claim success in this case. AOP_WRITEPAGE_ACTIVATE, and the
+ * page_mapped check below, must be avoided unless we're in reclaim.
+ */
+ if (!wbc->for_reclaim) {
+ set_page_dirty(page);
+ unlock_page(page);
+ return 0;
+ }
BUG_ON(page_mapped(page));

mapping = page->mapping;

2007-11-19 20:00:12

by David Brownell

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

> This addition certainly won't hurt. Did we ever get any feedback as to
> whether it actually helped?

ISTR that davem refused to try it, after reporting an
intermittent failure on the original patch (which only
addresses one end of that hardware race).

So, no ... but given we know that closing only one side
of the race isn't quite enough, I think we need it anyway.

- Dave

2007-11-19 22:32:51

by David Miller

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

From: David Brownell <[email protected]>
Date: Mon, 19 Nov 2007 11:59:55 -0800

> > This addition certainly won't hurt. Did we ever get any feedback as to
> > whether it actually helped?
>
> ISTR that davem refused to try it, after reporting an
> intermittent failure on the original patch (which only
> addresses one end of that hardware race).
>
> So, no ... but given we know that closing only one side
> of the race isn't quite enough, I think we need it anyway.

I think we should put all these changes in because at a minimum
it's a step in the right direction even if it doesn't close
the hole %100.

So please let's merge the mutex and the msleep() change in
ASAP, thanks.

2007-11-19 23:00:59

by Greg KH

[permalink] [raw]
Subject: Re: [patch 19/26] USB: mutual exclusion for EHCI init and port resets

On Mon, Nov 19, 2007 at 02:32:41PM -0800, David Miller wrote:
> From: David Brownell <[email protected]>
> Date: Mon, 19 Nov 2007 11:59:55 -0800
>
> > > This addition certainly won't hurt. Did we ever get any feedback as to
> > > whether it actually helped?
> >
> > ISTR that davem refused to try it, after reporting an
> > intermittent failure on the original patch (which only
> > addresses one end of that hardware race).
> >
> > So, no ... but given we know that closing only one side
> > of the race isn't quite enough, I think we need it anyway.
>
> I think we should put all these changes in because at a minimum
> it's a step in the right direction even if it doesn't close
> the hole %100.
>
> So please let's merge the mutex and the msleep() change in
> ASAP, thanks.

The msleep one is queued up for the next Linus pull, and after it goes
in, I'll add it to the -stable trees as well.

thanks,

greg k-h

2007-11-19 23:12:35

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 16/26] hptiop: avoid buffer overflow when returning sense data

On Mon, Nov 19, 2007 at 11:38:35AM -0700, Matthew Wilcox wrote:
> On Mon, Nov 19, 2007 at 10:19:12AM -0800, Greg Kroah-Hartman wrote:
> >
> > 2.6.22-stable review patch. If anyone has any objections, please let us
> > know.
>
> Makes sense to backport this.
>
> Acked-by: Matthew Wilcox <[email protected]>

Thanks for the review.

greg k-h

2007-11-19 23:12:48

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 04/26] writeback: dont propagate AOP_WRITEPAGE_ACTIVATE

On Mon, Nov 19, 2007 at 07:04:57PM +0000, Hugh Dickins wrote:
> On Mon, 19 Nov 2007, Greg Kroah-Hartman wrote:
> >
> > 2.6.22-stable review patch. If anyone has any objections, please let us
> > know.
> >
> > ------------------
> > From: Andrew Morton <[email protected]>
> >
> > patch e423003028183df54f039dfda8b58c49e78c89d7 in mainline.
> >
> > This is a writeback-internal marker but we're propagating it all the way back
> > to userspace!.
> >
> > Signed-off-by: Andrew Morton <[email protected]>
> > Signed-off-by: Linus Torvalds <[email protected]>
> > Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> It's fine by me that this should go into 2.6.22-stable, but then please
> also put in this related patch from 2.6.23-stable: it's arguable whether
> either are strictly needed (they were originally provoked by unionfs, in
> Ubuntu but not mainline), but more helpful to include than exclude them.
>
> Thanks,
> Hugh
>
>
> Subject: [patch 12/13] fix tmpfs BUG and AOP_WRITEPAGE_ACTIVATE

Ok, thanks, I've added this patch to the queue too.

greg k-h

2007-11-19 23:13:04

by Greg KH

[permalink] [raw]
Subject: Re: [stable] [patch 07/26] fix the softlockup watchdog to actually work

On Mon, Nov 19, 2007 at 08:02:42PM +0100, Ingo Molnar wrote:
>
> * Greg Kroah-Hartman <[email protected]> wrote:
>
> > 2.6.22-stable review patch. If anyone has any objections, please let
> > us know.
>
> we shouldnt do this for 2.6.22 - it has no proper cpu_clock() facility
> like .23 or .24. So lets leave this alone.

Ok, I've now dropped it, thanks for letting us know.

greg k-h