From: Chris Wright Date: Fri, 12 Jan 2007 16:07:43 +0000 (-0800) Subject: really commit releases/2.6.19.2 X-Git-Tag: v2.6.19.2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2532c0bbafdf71175dc0306944e5f6a8c8eb3d6f;p=thirdparty%2Fkernel%2Fstable-queue.git really commit releases/2.6.19.2 --- diff --git a/releases/2.6.19.2/arm-add-sys_-at-syscalls.patch b/releases/2.6.19.2/arm-add-sys_-at-syscalls.patch new file mode 100644 index 00000000000..daf2fe214bc --- /dev/null +++ b/releases/2.6.19.2/arm-add-sys_-at-syscalls.patch @@ -0,0 +1,61 @@ +From stable-bounces@linux.kernel.org Wed Dec 13 06:18:12 2006 +Date: Wed, 13 Dec 2006 14:12:15 +0000 +From: Russell King +To: stable@kernel.org +Message-ID: <20061213141215.GA21171@dyn-67.arm.linux.org.uk> +Subject: ARM: Add sys_*at syscalls + +Later glibc requires the *at syscalls. Add them. + +Signed-off-by: Russell King +Signed-off-by: Chris Wright +--- + arch/arm/kernel/calls.S | 13 +++++++++++++ + include/asm-arm/unistd.h | 13 +++++++++++++ + 2 files changed, 26 insertions(+) + +bca0b8e75f6b7cf52cf52c967286b72d84f9b37e +--- linux-2.6.19.1.orig/arch/arm/kernel/calls.S ++++ linux-2.6.19.1/arch/arm/kernel/calls.S +@@ -331,6 +331,19 @@ + CALL(sys_mbind) + /* 320 */ CALL(sys_get_mempolicy) + CALL(sys_set_mempolicy) ++ CALL(sys_openat) ++ CALL(sys_mkdirat) ++ CALL(sys_mknodat) ++/* 325 */ CALL(sys_fchownat) ++ CALL(sys_futimesat) ++ CALL(sys_fstatat64) ++ CALL(sys_unlinkat) ++ CALL(sys_renameat) ++/* 330 */ CALL(sys_linkat) ++ CALL(sys_symlinkat) ++ CALL(sys_readlinkat) ++ CALL(sys_fchmodat) ++ CALL(sys_faccessat) + #ifndef syscalls_counted + .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls + #define syscalls_counted +--- linux-2.6.19.1.orig/include/asm-arm/unistd.h ++++ linux-2.6.19.1/include/asm-arm/unistd.h +@@ -347,6 +347,19 @@ + #define __NR_mbind (__NR_SYSCALL_BASE+319) + #define __NR_get_mempolicy (__NR_SYSCALL_BASE+320) + #define __NR_set_mempolicy (__NR_SYSCALL_BASE+321) ++#define __NR_openat (__NR_SYSCALL_BASE+322) ++#define __NR_mkdirat (__NR_SYSCALL_BASE+323) ++#define __NR_mknodat (__NR_SYSCALL_BASE+324) ++#define __NR_fchownat (__NR_SYSCALL_BASE+325) ++#define __NR_futimesat (__NR_SYSCALL_BASE+326) ++#define __NR_fstatat64 (__NR_SYSCALL_BASE+327) ++#define __NR_unlinkat (__NR_SYSCALL_BASE+328) ++#define __NR_renameat (__NR_SYSCALL_BASE+329) ++#define __NR_linkat (__NR_SYSCALL_BASE+330) ++#define __NR_symlinkat (__NR_SYSCALL_BASE+331) ++#define __NR_readlinkat (__NR_SYSCALL_BASE+332) ++#define __NR_fchmodat (__NR_SYSCALL_BASE+333) ++#define __NR_faccessat (__NR_SYSCALL_BASE+334) + + /* + * The following SWIs are ARM private. diff --git a/releases/2.6.19.2/asix-fix-typo-for-ax88772-phy-selection.patch b/releases/2.6.19.2/asix-fix-typo-for-ax88772-phy-selection.patch new file mode 100644 index 00000000000..d430059c033 --- /dev/null +++ b/releases/2.6.19.2/asix-fix-typo-for-ax88772-phy-selection.patch @@ -0,0 +1,34 @@ +From stable-bounces@linux.kernel.org Fri Jan 5 09:41:36 2007 +Date: Fri, 05 Jan 2007 12:34:05 -0500 +From: David Hollis +To: stable@kernel.org +Message-id: <1168018445.3549.7.camel@dhollis-lnx.sunera.com> +Subject: asix: Fix typo for AX88772 PHY Selection + +The attached patch fixes a PHY selection problem that prevents AX88772 +based devices (Linksys USB200Mv2, etc) devices from working. The +interface comes up and everything seems fine except the device doesn't +send/receive any packets. The one-liner attached fixes this issue and +makes the devices usable again. + +Signed-off-by: David Hollis +Signed-off-by: Chris Wright +--- +Patch has already been applied for 2.6.20+ kernels but it would be very +helpful for end-users/distributions to have this fixed in the 2.6.19 +series as well. + + drivers/usb/net/asix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/usb/net/asix.c ++++ linux-2.6.19.1/drivers/usb/net/asix.c +@@ -920,7 +920,7 @@ static int ax88772_bind(struct usbnet *d + goto out2; + + if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, +- 0x0000, 0, 0, buf)) < 0) { ++ 1, 0, 0, buf)) < 0) { + dbg("Select PHY #1 failed: %d", ret); + goto out2; + } diff --git a/releases/2.6.19.2/bluetooth-add-packet-size-checks-for-capi-messages.patch b/releases/2.6.19.2/bluetooth-add-packet-size-checks-for-capi-messages.patch new file mode 100644 index 00000000000..bef4f679544 --- /dev/null +++ b/releases/2.6.19.2/bluetooth-add-packet-size-checks-for-capi-messages.patch @@ -0,0 +1,121 @@ +From vendor-sec-admin@lst.de Mon Dec 11 06:28:38 2006 +Message-ID: <457D68B0.6060503@redhat.com> +From: Marcel Holtmann +CC: Al Viro +Subject: Bluetooth: Add packet size checks for CAPI messages (CVE-2006-6106) +Date: Mon, 11 Dec 2006 15:18:24 +0100 + +With malformed packets it might be possible to overwrite internal +CMTP and CAPI data structures. This patch adds additional length +checks to prevent these kinds of remote attacks. + +Signed-off-by: Marcel Holtmann +Signed-off-by: Chris Wright +--- + + net/bluetooth/cmtp/capi.c | 39 +++++++++++++++++++++++++++++++++------ + 1 file changed, 33 insertions(+), 6 deletions(-) + +--- linux-2.6.19.1.orig/net/bluetooth/cmtp/capi.c ++++ linux-2.6.19.1/net/bluetooth/cmtp/capi.c +@@ -196,6 +196,9 @@ static void cmtp_recv_interopmsg(struct + + switch (CAPIMSG_SUBCOMMAND(skb->data)) { + case CAPI_CONF: ++ if (skb->len < CAPI_MSG_BASELEN + 10) ++ break; ++ + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); + info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); + +@@ -226,6 +229,9 @@ static void cmtp_recv_interopmsg(struct + break; + + case CAPI_FUNCTION_GET_PROFILE: ++ if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile)) ++ break; ++ + controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); + msgnum = CAPIMSG_MSGID(skb->data); + +@@ -246,17 +252,26 @@ static void cmtp_recv_interopmsg(struct + break; + + case CAPI_FUNCTION_GET_MANUFACTURER: ++ if (skb->len < CAPI_MSG_BASELEN + 15) ++ break; ++ + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); + + if (!info && ctrl) { ++ int len = min_t(uint, CAPI_MANUFACTURER_LEN, ++ skb->data[CAPI_MSG_BASELEN + 14]); ++ ++ memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN); + strncpy(ctrl->manu, +- skb->data + CAPI_MSG_BASELEN + 15, +- skb->data[CAPI_MSG_BASELEN + 14]); ++ skb->data + CAPI_MSG_BASELEN + 15, len); + } + + break; + + case CAPI_FUNCTION_GET_VERSION: ++ if (skb->len < CAPI_MSG_BASELEN + 32) ++ break; ++ + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); + + if (!info && ctrl) { +@@ -269,13 +284,18 @@ static void cmtp_recv_interopmsg(struct + break; + + case CAPI_FUNCTION_GET_SERIAL_NUMBER: ++ if (skb->len < CAPI_MSG_BASELEN + 17) ++ break; ++ + controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); + + if (!info && ctrl) { ++ int len = min_t(uint, CAPI_SERIAL_LEN, ++ skb->data[CAPI_MSG_BASELEN + 16]); ++ + memset(ctrl->serial, 0, CAPI_SERIAL_LEN); + strncpy(ctrl->serial, +- skb->data + CAPI_MSG_BASELEN + 17, +- skb->data[CAPI_MSG_BASELEN + 16]); ++ skb->data + CAPI_MSG_BASELEN + 17, len); + } + + break; +@@ -284,14 +304,18 @@ static void cmtp_recv_interopmsg(struct + break; + + case CAPI_IND: ++ if (skb->len < CAPI_MSG_BASELEN + 6) ++ break; ++ + func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); + + if (func == CAPI_FUNCTION_LOOPBACK) { ++ int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6, ++ skb->data[CAPI_MSG_BASELEN + 5]); + appl = CAPIMSG_APPID(skb->data); + msgnum = CAPIMSG_MSGID(skb->data); + cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, +- skb->data + CAPI_MSG_BASELEN + 6, +- skb->data[CAPI_MSG_BASELEN + 5]); ++ skb->data + CAPI_MSG_BASELEN + 6, len); + } + + break; +@@ -309,6 +333,9 @@ void cmtp_recv_capimsg(struct cmtp_sessi + + BT_DBG("session %p skb %p len %d", session, skb, skb->len); + ++ if (skb->len < CAPI_MSG_BASELEN) ++ return; ++ + if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { + cmtp_recv_interopmsg(session, skb); + return; diff --git a/releases/2.6.19.2/bonding-incorrect-bonding-state-reported-via-ioctl.patch b/releases/2.6.19.2/bonding-incorrect-bonding-state-reported-via-ioctl.patch new file mode 100644 index 00000000000..551054c828c --- /dev/null +++ b/releases/2.6.19.2/bonding-incorrect-bonding-state-reported-via-ioctl.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Tue Nov 21 11:28:41 2006 +Resent-From: agospoda@redhat.com +Date: Tue, 21 Nov 2006 11:46:44 -0500 +From: Andy Gospodarek +To: stable@kernel.org +Message-ID: <20061121164643.GA2539@gospo.rdu.redhat.com> +Cc: fubar@us.ibm.com, ctindel@users.sourceforge.net +Subject: bonding: incorrect bonding state reported via ioctl + +This is a small fix-up to finish out the work done by Jay Vosburgh to +add carrier-state support for bonding devices. The output in +/proc/net/bonding/bondX was correct, but when collecting the same info +via an iotcl it could still be incorrect. + +Signed-off-by: Andy Gospodarek +Cc: Jeff Garzik +Cc: Stephen Hemminger +Signed-off-by: Andrew Morton +Signed-off-by: Jeff Garzik +Signed-off-by: Chris Wright +--- + + drivers/net/bonding/bond_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/net/bonding/bond_main.c ++++ linux-2.6.19.1/drivers/net/bonding/bond_main.c +@@ -3675,7 +3675,7 @@ static int bond_do_ioctl(struct net_devi + mii->val_out = 0; + read_lock_bh(&bond->lock); + read_lock(&bond->curr_slave_lock); +- if (bond->curr_active_slave) { ++ if (netif_carrier_ok(bond->dev)) { + mii->val_out = BMSR_LSTATUS; + } + read_unlock(&bond->curr_slave_lock); diff --git a/releases/2.6.19.2/buglet-in-vmscan.c.patch b/releases/2.6.19.2/buglet-in-vmscan.c.patch new file mode 100644 index 00000000000..5c94c29f276 --- /dev/null +++ b/releases/2.6.19.2/buglet-in-vmscan.c.patch @@ -0,0 +1,33 @@ +From stable-bounces@linux.kernel.org Fri Dec 29 16:57:04 2006 +Message-Id: <200612300049.kBU0nJHN008167@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 29 Dec 2006 16:48:59 -0800 +Cc: akpm@osdl.org, clameter@engr.sgi.com, stable@kernel.org, sgoel01@yahoo.com +Subject: Buglet in vmscan.c + +From: Shantanu Goel + +Fix a rather obvious buglet. Noticed while instrumenting the VM using +/proc/vmstat. + +Cc: Christoph Lameter +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + mm/vmscan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/mm/vmscan.c ++++ linux-2.6.19.1/mm/vmscan.c +@@ -691,7 +691,7 @@ static unsigned long shrink_inactive_lis + __count_vm_events(KSWAPD_STEAL, nr_freed); + } else + __count_zone_vm_events(PGSCAN_DIRECT, zone, nr_scan); +- __count_vm_events(PGACTIVATE, nr_freed); ++ __count_zone_vm_events(PGSTEAL, zone, nr_freed); + + if (nr_taken == 0) + goto done; diff --git a/releases/2.6.19.2/cciss-fix-xfer_read-xfer_write-in-do_cciss_request.patch b/releases/2.6.19.2/cciss-fix-xfer_read-xfer_write-in-do_cciss_request.patch new file mode 100644 index 00000000000..f4d44b0af4f --- /dev/null +++ b/releases/2.6.19.2/cciss-fix-xfer_read-xfer_write-in-do_cciss_request.patch @@ -0,0 +1,35 @@ +From stable-bounces@linux.kernel.org Sat Dec 23 12:21:40 2006 +Date: Sat, 23 Dec 2006 15:11:58 -0500 +From: Chuck Ebbert <76306.1226@compuserve.com> +To: linux-stable +Message-ID: <200612231514_MC3-1-D628-9FB6@compuserve.com> +Content-Disposition: inline +Cc: Mike Miller +Subject: cciss: fix XFER_READ/XFER_WRITE in do_cciss_request + +From: Mike Miller + +This patch fixes a stupid bug. Sometime during the 2tb enhancement I ended up +replacing the macros XFER_READ and XFER_WRITE with h->cciss_read and +h->cciss_write respectively. It seemed to work somehow at least on x86_64 and +ia64. I don't know how. But people started complaining about command timeouts +on older controllers like the 64xx series and only on ia32. This resolves the +issue reproduced in our lab. Please consider this for inclusion. + +Signed-off-by: Mike Miller +Signed-off-by: Chris Wright +--- + drivers/block/cciss.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/block/cciss.c ++++ linux-2.6.19.1/drivers/block/cciss.c +@@ -2530,7 +2530,7 @@ static void do_cciss_request(request_que + c->Request.Type.Type = TYPE_CMD; // It is a command. + c->Request.Type.Attribute = ATTR_SIMPLE; + c->Request.Type.Direction = +- (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; ++ (rq_data_dir(creq) == READ) ? XFER_READ : XFER_WRITE; + c->Request.Timeout = 0; // Don't time out + c->Request.CDB[0] = + (rq_data_dir(creq) == READ) ? h->cciss_read : h->cciss_write; diff --git a/releases/2.6.19.2/connector-some-fixes-for-ia64-unaligned-access-errors.patch b/releases/2.6.19.2/connector-some-fixes-for-ia64-unaligned-access-errors.patch new file mode 100644 index 00000000000..df0056652bb --- /dev/null +++ b/releases/2.6.19.2/connector-some-fixes-for-ia64-unaligned-access-errors.patch @@ -0,0 +1,85 @@ +From stable-bounces@linux.kernel.org Fri Jan 5 16:45:00 2007 +Message-Id: <200701060037.l060bW40013427@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 05 Jan 2007 16:37:05 -0800 +Cc: akpm@osdl.org, johnpol@2ka.mipt.ru, tony.luck@intel.com, stable@kernel.org, erikj@sgi.com, davem@davemloft.net +Subject: connector: some fixes for ia64 unaligned access errors + +From: Erik Jacobson + +On ia64, the various functions that make up cn_proc.c cause kernel +unaligned access errors. + +If you are using these, for example, to get notification about all tasks +forking and exiting, you get multiple unaligned access errors per process. + +Use put_unaligned() in the appropriate palces to fix this. + +Signed-off-by: Erik Jacobson +Cc: Evgeniy Polyakov +Cc: Tony Luck +Cc: +Cc: "David S. Miller" +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + drivers/connector/cn_proc.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +--- linux-2.6.19.1.orig/drivers/connector/cn_proc.c ++++ linux-2.6.19.1/drivers/connector/cn_proc.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #include + +@@ -60,7 +61,7 @@ void proc_fork_connector(struct task_str + ev = (struct proc_event*)msg->data; + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- ev->timestamp_ns = timespec_to_ns(&ts); ++ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + ev->what = PROC_EVENT_FORK; + ev->event_data.fork.parent_pid = task->real_parent->pid; + ev->event_data.fork.parent_tgid = task->real_parent->tgid; +@@ -88,7 +89,7 @@ void proc_exec_connector(struct task_str + ev = (struct proc_event*)msg->data; + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- ev->timestamp_ns = timespec_to_ns(&ts); ++ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + ev->what = PROC_EVENT_EXEC; + ev->event_data.exec.process_pid = task->pid; + ev->event_data.exec.process_tgid = task->tgid; +@@ -124,7 +125,7 @@ void proc_id_connector(struct task_struc + return; + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- ev->timestamp_ns = timespec_to_ns(&ts); ++ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + + memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); + msg->ack = 0; /* not used */ +@@ -146,7 +147,7 @@ void proc_exit_connector(struct task_str + ev = (struct proc_event*)msg->data; + get_seq(&msg->seq, &ev->cpu); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- ev->timestamp_ns = timespec_to_ns(&ts); ++ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + ev->what = PROC_EVENT_EXIT; + ev->event_data.exit.process_pid = task->pid; + ev->event_data.exit.process_tgid = task->tgid; +@@ -181,7 +182,7 @@ static void cn_proc_ack(int err, int rcv + ev = (struct proc_event*)msg->data; + msg->seq = rcvd_seq; + ktime_get_ts(&ts); /* get high res monotonic timestamp */ +- ev->timestamp_ns = timespec_to_ns(&ts); ++ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); + ev->cpu = -1; + ev->what = PROC_EVENT_NONE; + ev->event_data.ack.err = err; diff --git a/releases/2.6.19.2/corrupted-cramfs-filesystems-cause-kernel-oops.patch b/releases/2.6.19.2/corrupted-cramfs-filesystems-cause-kernel-oops.patch new file mode 100644 index 00000000000..5fa5308191e --- /dev/null +++ b/releases/2.6.19.2/corrupted-cramfs-filesystems-cause-kernel-oops.patch @@ -0,0 +1,47 @@ +From stable-bounces@linux.kernel.org Sat Dec 30 15:33:45 2006 +Message-ID: <4596F606.2090504@gentoo.org> +Date: Sat, 30 Dec 2006 18:28:06 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: phillip@lougher.org.uk +Subject: corrupted cramfs filesystems cause kernel oops (CVE-2006-5823) + +From: Phillip Lougher + +Steve Grubb's fzfuzzer tool (http://people.redhat.com/sgrubb/files/ +fsfuzzer-0.6.tar.gz) generates corrupt Cramfs filesystems which cause +Cramfs to kernel oops in cramfs_uncompress_block(). The cause of the oops +is an unchecked corrupted block length field read by cramfs_readpage(). + +This patch adds a sanity check to cramfs_readpage() which checks that the +block length field is sensible. The (PAGE_CACHE_SIZE << 1) size check is +intentional, even though the uncompressed data is not going to be larger +than PAGE_CACHE_SIZE, gzip sometimes generates compressed data larger than +the original source data. Mkcramfs checks that the compressed size is +always less than or equal to PAGE_CACHE_SIZE << 1. Of course Cramfs could +use the original uncompressed data in this case, but it doesn't. + +Signed-off-by: Phillip Lougher +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- +Date: Thu, 7 Dec 2006 04:37:20 +0000 (-0800) +Subject: [PATCH] corrupted cramfs filesystems cause kernel oops +X-Git-Tag: v2.6.20-rc1 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=8bb0269160df2a60764013994d0bc5165406cf4a + + fs/cramfs/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- linux-2.6.19.1.orig/fs/cramfs/inode.c ++++ linux-2.6.19.1/fs/cramfs/inode.c +@@ -481,6 +481,8 @@ static int cramfs_readpage(struct file * + pgdata = kmap(page); + if (compr_len == 0) + ; /* hole */ ++ else if (compr_len > (PAGE_CACHE_SIZE << 1)) ++ printk(KERN_ERR "cramfs: bad compressed blocksize %u\n", compr_len); + else { + mutex_lock(&read_mutex); + bytes_filled = cramfs_uncompress_block(pgdata, diff --git a/releases/2.6.19.2/dm-crypt-select-crypto_cbc.patch b/releases/2.6.19.2/dm-crypt-select-crypto_cbc.patch new file mode 100644 index 00000000000..f432f370197 --- /dev/null +++ b/releases/2.6.19.2/dm-crypt-select-crypto_cbc.patch @@ -0,0 +1,27 @@ +From stable-bounces@linux.kernel.org Sat Dec 9 14:56:35 2006 +Date: Sun, 10 Dec 2006 09:50:36 +1100 +Message-ID: <20061209225035.GA12802@gondor.apana.org.au> +From: Herbert Xu +To: Rene Herman +Cc: torvalds@osdl.org, "David S. Miller" , stable@kernel.org +Subject: dm-crypt: Select CRYPTO_CBC + +As CBC is the default chaining method for cryptoloop, we should select +it from cryptoloop to ease the transition. Spotted by Rene Herman. + +Signed-off-by: Herbert Xu +Signed-off-by: Chris Wright +--- + drivers/md/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +--- linux-2.6.19.1.orig/drivers/md/Kconfig ++++ linux-2.6.19.1/drivers/md/Kconfig +@@ -215,6 +215,7 @@ config DM_CRYPT + tristate "Crypt target support" + depends on BLK_DEV_DM && EXPERIMENTAL + select CRYPTO ++ select CRYPTO_CBC + ---help--- + This device-mapper target allows you to create a device that + transparently encrypts the data on it. You'll need to activate diff --git a/releases/2.6.19.2/dvb-core-fix-bug-in-crc-32-checking-on-64-bit-systems.patch b/releases/2.6.19.2/dvb-core-fix-bug-in-crc-32-checking-on-64-bit-systems.patch new file mode 100644 index 00000000000..e93d74b053e --- /dev/null +++ b/releases/2.6.19.2/dvb-core-fix-bug-in-crc-32-checking-on-64-bit-systems.patch @@ -0,0 +1,45 @@ +From stable-bounces@linux.kernel.org Wed Jan 3 20:28:12 2007 +Message-ID: <459C80A0.7080509@linuxtv.org> +Date: Wed, 03 Jan 2007 23:20:48 -0500 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , Ang Way Chuang +Subject: dvb-core: fix bug in CRC-32 checking on 64-bit systems + +From: Ang Way Chuang + +CRC-32 checking during ULE decapsulation always failed on x86_64 systems due +to the size of a variable used to store CRC. This bug was discovered on +Fedora Core 6 with kernel-2.6.18-1.2849. The i386 counterpart has no such +problem. This patch has been tested on 64-bit system as well as 32-bit system. + +Signed-off-by: Ang Way Chuang +Signed-off-by: Michael Krufky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Chris Wright +--- +(cherry picked from commit dedcefb085fe98a1feaf63590fe2fc7e0ecb1987) + + drivers/media/dvb/dvb-core/dvb_net.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/drivers/media/dvb/dvb-core/dvb_net.c ++++ linux-2.6.19.1/drivers/media/dvb/dvb-core/dvb_net.c +@@ -604,7 +604,7 @@ static void dvb_net_ule( struct net_devi + { &utype, sizeof utype }, + { priv->ule_skb->data, priv->ule_skb->len - 4 } + }; +- unsigned long ule_crc = ~0L, expected_crc; ++ u32 ule_crc = ~0L, expected_crc; + if (priv->ule_dbit) { + /* Set D-bit for CRC32 verification, + * if it was set originally. */ +@@ -617,7 +617,7 @@ static void dvb_net_ule( struct net_devi + *((u8 *)priv->ule_skb->tail - 2) << 8 | + *((u8 *)priv->ule_skb->tail - 1); + if (ule_crc != expected_crc) { +- printk(KERN_WARNING "%lu: CRC32 check FAILED: %#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", ++ printk(KERN_WARNING "%lu: CRC32 check FAILED: %08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n", + priv->ts_count, ule_crc, expected_crc, priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned short *)from_where : 0); + + #ifdef ULE_DEBUG diff --git a/releases/2.6.19.2/dvb-lgdt330x-fix-signal-lock-status-detection-bug.patch b/releases/2.6.19.2/dvb-lgdt330x-fix-signal-lock-status-detection-bug.patch new file mode 100644 index 00000000000..ec4fbe1cf0d --- /dev/null +++ b/releases/2.6.19.2/dvb-lgdt330x-fix-signal-lock-status-detection-bug.patch @@ -0,0 +1,48 @@ +From stable-bounces@linux.kernel.org Mon Dec 11 21:40:14 2006 +Message-ID: <457E3F63.2010208@linuxtv.org> +Date: Tue, 12 Dec 2006 00:34:27 -0500 +From: Michael Krufky +To: stable@kernel.org +Cc: v4l-dvb maintainer list , Adrian Bunk +Subject: DVB: lgdt330x: fix signal / lock status detection bug + +In some cases when using VSB, the AGC status register has been known to +falsely report "no signal" when in fact there is a carrier lock. The +datasheet labels these status flags as QAM only, yet the lgdt330x +module is using these flags for both QAM and VSB. + +This patch allows for the carrier recovery lock status register to be +tested, even if the agc signal status register falsely reports no signal. + +Thanks to jcrews from #linuxtv in irc, for initially reporting this bug. + +Signed-off-by: Michael Krufky +Signed-off-by: Chris Wright + +--- + + drivers/media/dvb/frontends/lgdt330x.c | 6 ------ + 1 file changed, 6 deletions(-) + +--- linux-2.6.19.1.orig/drivers/media/dvb/frontends/lgdt330x.c ++++ linux-2.6.19.1/drivers/media/dvb/frontends/lgdt330x.c +@@ -435,9 +435,6 @@ static int lgdt3302_read_status(struct d + /* Test signal does not exist flag */ + /* as well as the AGC lock flag. */ + *status |= FE_HAS_SIGNAL; +- } else { +- /* Without a signal all other status bits are meaningless */ +- return 0; + } + + /* +@@ -500,9 +497,6 @@ static int lgdt3303_read_status(struct d + /* Test input signal does not exist flag */ + /* as well as the AGC lock flag. */ + *status |= FE_HAS_SIGNAL; +- } else { +- /* Without a signal all other status bits are meaningless */ +- return 0; + } + + /* Carrier Recovery Lock Status Register */ diff --git a/releases/2.6.19.2/ebtables-don-t-compute-gap-before-checking-struct-type.patch b/releases/2.6.19.2/ebtables-don-t-compute-gap-before-checking-struct-type.patch new file mode 100644 index 00000000000..cc834d8fbf1 --- /dev/null +++ b/releases/2.6.19.2/ebtables-don-t-compute-gap-before-checking-struct-type.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Thu Jan 4 00:13:21 2007 +Date: Thu, 4 Jan 2007 02:59:56 -0500 +From: Chuck Ebbert <76306.1226@compuserve.com> +To: "stable@kernel.org" +Message-ID: <200701040303_MC3-1-D740-18D3@compuserve.com> +Cc: Patrick McHardy +Subject: ebtables: don't compute gap before checking struct type + +We cannot compute the gap until we know we have a 'struct ebt_entry' +and not 'struct ebt_entries'. Failure to check can cause crash. + +Tested-by: Santiago Garcia Mantinan +Acked-by: Al Viro +Acked-by: Patrick McHardy +Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> +Signed-off-by: Chris Wright +--- + net/bridge/netfilter/ebtables.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/net/bridge/netfilter/ebtables.c ++++ linux-2.6.19.1/net/bridge/netfilter/ebtables.c +@@ -575,7 +575,7 @@ ebt_check_entry(struct ebt_entry *e, str + struct ebt_entry_target *t; + struct ebt_target *target; + unsigned int i, j, hook = 0, hookmask = 0; +- size_t gap = e->next_offset - e->target_offset; ++ size_t gap; + int ret; + + /* don't mess with the struct ebt_entries */ +@@ -625,6 +625,7 @@ ebt_check_entry(struct ebt_entry *e, str + if (ret != 0) + goto cleanup_watchers; + t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); ++ gap = e->next_offset - e->target_offset; + target = find_target_lock(t->u.name, &ret, &ebt_mutex); + if (!target) + goto cleanup_watchers; diff --git a/releases/2.6.19.2/ext2-skip-pages-past-number-of-blocks-in-ext2_find_entry.patch b/releases/2.6.19.2/ext2-skip-pages-past-number-of-blocks-in-ext2_find_entry.patch new file mode 100644 index 00000000000..da53e3a4de1 --- /dev/null +++ b/releases/2.6.19.2/ext2-skip-pages-past-number-of-blocks-in-ext2_find_entry.patch @@ -0,0 +1,47 @@ +From stable-bounces@linux.kernel.org Sat Dec 30 15:36:19 2006 +Message-ID: <4596F698.5070505@gentoo.org> +Date: Sat, 30 Dec 2006 18:30:32 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: sandeen@redhat.com +Subject: ext2: skip pages past number of blocks in ext2_find_entry (CVE-2006-6054) + +From: Eric Sandeen + +This one was pointed out on the MOKB site: +http://kernelfun.blogspot.com/2006/11/mokb-09-11-2006-linux-26x-ext2checkpage.html + +If a directory's i_size is corrupted, ext2_find_entry() will keep processing +pages until the i_size is reached, even if there are no more blocks associated +with the directory inode. This patch puts in some minimal sanity-checking +so that we don't keep checking pages (and issuing errors) if we know there +can be no more data to read, based on the block count of the directory inode. + +This is somewhat similar in approach to the ext3 patch I sent earlier this +year. + +Signed-off-by: Eric Sandeen +Signed-off-by: Chris Wright +--- +Not upstream yet + + fs/ext2/dir.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- linux-2.6.19.1.orig/fs/ext2/dir.c ++++ linux-2.6.19.1/fs/ext2/dir.c +@@ -368,6 +368,14 @@ struct ext2_dir_entry_2 * ext2_find_entr + } + if (++n >= npages) + n = 0; ++ /* next page is past the blocks we've got */ ++ if (unlikely(n > (dir->i_blocks >> (PAGE_CACHE_SHIFT - 9)))) { ++ ext2_error(dir->i_sb, __FUNCTION__, ++ "dir %lu size %lld exceeds block count %llu", ++ dir->i_ino, dir->i_size, ++ (unsigned long long)dir->i_blocks); ++ goto out; ++ } + } while (n != start); + out: + return NULL; diff --git a/releases/2.6.19.2/fix-aoe-without-scatter-gather.patch b/releases/2.6.19.2/fix-aoe-without-scatter-gather.patch new file mode 100644 index 00000000000..db07679a475 --- /dev/null +++ b/releases/2.6.19.2/fix-aoe-without-scatter-gather.patch @@ -0,0 +1,89 @@ +From stable-bounces@linux.kernel.org Fri Dec 22 01:16:04 2006 +Message-Id: <200612220909.kBM99N3M018750@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 22 Dec 2006 01:09:21 -0800 +Cc: akpm@osdl.org, greg@kroah.com, boddingt@optusnet.com.au, ecashin@coraid.com, stable@kernel.org +Subject: fix aoe without scatter-gather [Bug 7662] + +From: Ed L Cashin + +Fix a bug that only appears when AoE goes over a network card that does not +support scatter-gather. The headers in the linear part of the skb appeared +to be larger than they really were, resulting in data that was offset by 24 +bytes. + +This patch eliminates the offset data on cards that don't support +scatter-gather or have had scatter-gather turned off. There remains an +unrelated issue that I'll address in a separate email. + +Fixes bugzilla #7662 + +Signed-off-by: "Ed L. Cashin" +Cc: +Cc: Greg KH +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + drivers/block/aoe/aoecmd.c | 13 ++++++------- + 1 file changed, 6 insertions(+), 7 deletions(-) + +--- linux-2.6.19.1.orig/drivers/block/aoe/aoecmd.c ++++ linux-2.6.19.1/drivers/block/aoe/aoecmd.c +@@ -30,8 +30,6 @@ new_skb(ulong len) + skb->nh.raw = skb->mac.raw = skb->data; + skb->protocol = __constant_htons(ETH_P_AOE); + skb->priority = 0; +- skb_put(skb, len); +- memset(skb->head, 0, len); + skb->next = skb->prev = NULL; + + /* tell the network layer not to perform IP checksums +@@ -122,8 +120,8 @@ aoecmd_ata_rw(struct aoedev *d, struct f + skb = f->skb; + h = (struct aoe_hdr *) skb->mac.raw; + ah = (struct aoe_atahdr *) (h+1); +- skb->len = sizeof *h + sizeof *ah; +- memset(h, 0, ETH_ZLEN); ++ skb_put(skb, sizeof *h + sizeof *ah); ++ memset(h, 0, skb->len); + f->tag = aoehdr_atainit(d, h); + f->waited = 0; + f->buf = buf; +@@ -149,7 +147,6 @@ aoecmd_ata_rw(struct aoedev *d, struct f + skb->len += bcnt; + skb->data_len = bcnt; + } else { +- skb->len = ETH_ZLEN; + writebit = 0; + } + +@@ -206,6 +203,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigne + printk(KERN_INFO "aoe: skb alloc failure\n"); + continue; + } ++ skb_put(skb, sizeof *h + sizeof *ch); + skb->dev = ifp; + if (sl_tail == NULL) + sl_tail = skb; +@@ -243,6 +241,7 @@ freeframe(struct aoedev *d) + continue; + if (atomic_read(&skb_shinfo(f->skb)->dataref) == 1) { + skb_shinfo(f->skb)->nr_frags = f->skb->data_len = 0; ++ skb_trim(f->skb, 0); + return f; + } + n++; +@@ -698,8 +697,8 @@ aoecmd_ata_id(struct aoedev *d) + skb = f->skb; + h = (struct aoe_hdr *) skb->mac.raw; + ah = (struct aoe_atahdr *) (h+1); +- skb->len = ETH_ZLEN; +- memset(h, 0, ETH_ZLEN); ++ skb_put(skb, sizeof *h + sizeof *ah); ++ memset(h, 0, skb->len); + f->tag = aoehdr_atainit(d, h); + f->waited = 0; + diff --git a/releases/2.6.19.2/fix-for-shmem_truncate_range-bug_on.patch b/releases/2.6.19.2/fix-for-shmem_truncate_range-bug_on.patch new file mode 100644 index 00000000000..752305031c5 --- /dev/null +++ b/releases/2.6.19.2/fix-for-shmem_truncate_range-bug_on.patch @@ -0,0 +1,42 @@ +From stable-bounces@linux.kernel.org Fri Dec 22 01:13:06 2006 +Message-Id: <200612220906.kBM96PM4018647@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 22 Dec 2006 01:06:23 -0800 +Cc: akpm@osdl.org, hugh@veritas.com, pbadari@us.ibm.com, stable@kernel.org +Subject: Fix for shmem_truncate_range() BUG_ON() + +From: Badari Pulavarty + +Ran into BUG() while doing madvise(REMOVE) testing. If we are punching a +hole into shared memory segment using madvise(REMOVE) and the entire hole +is below the indirect blocks, we hit following assert. + + BUG_ON(limit <= SHMEM_NR_DIRECT); + +Signed-off-by: Badari Pulavarty +Cc: Hugh Dickins +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + mm/shmem.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/mm/shmem.c ++++ linux-2.6.19.1/mm/shmem.c +@@ -515,7 +515,12 @@ static void shmem_truncate_range(struct + size = SHMEM_NR_DIRECT; + nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size); + } +- if (!topdir) ++ ++ /* ++ * If there are no indirect blocks or we are punching a hole ++ * below indirect blocks, nothing to be done. ++ */ ++ if (!topdir || (punch_hole && (limit <= SHMEM_NR_DIRECT))) + goto done2; + + BUG_ON(limit <= SHMEM_NR_DIRECT); diff --git a/releases/2.6.19.2/fix-incorrect-user-space-access-locking-in-mincore.patch b/releases/2.6.19.2/fix-incorrect-user-space-access-locking-in-mincore.patch new file mode 100644 index 00000000000..3bf473bb687 --- /dev/null +++ b/releases/2.6.19.2/fix-incorrect-user-space-access-locking-in-mincore.patch @@ -0,0 +1,246 @@ +From 2f77d107050abc14bc393b34bdb7b91cf670c250 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Sat, 16 Dec 2006 09:44:32 -0800 +Subject: Fix incorrect user space access locking in mincore() (CVE-2006-4814) + +Doug Chapman noticed that mincore() will doa "copy_to_user()" of the +result while holding the mmap semaphore for reading, which is a big +no-no. While a recursive read-lock on a semaphore in the case of a page +fault happens to work, we don't actually allow them due to deadlock +schenarios with writers due to fairness issues. + +Doug and Marcel sent in a patch to fix it, but I decided to just rewrite +the mess instead - not just fixing the locking problem, but making the +code smaller and (imho) much easier to understand. + +Cc: Doug Chapman +Cc: Marcel Holtmann +Cc: Hugh Dickins +Cc: Andrew Morton +[chrisw: fold in subsequent fix: 4fb23e439ce0] +Acked-by: Hugh Dickins +[chrisw: fold in subsequent fix: 825020c3866e] +Signed-off-by: Oleg Nesterov +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- + mm/mincore.c | 181 +++++++++++++++++++++++++---------------------------------- + 1 file changed, 77 insertions(+), 104 deletions(-) + +--- linux-2.6.19.1.orig/mm/mincore.c ++++ linux-2.6.19.1/mm/mincore.c +@@ -1,7 +1,7 @@ + /* + * linux/mm/mincore.c + * +- * Copyright (C) 1994-1999 Linus Torvalds ++ * Copyright (C) 1994-2006 Linus Torvalds + */ + + /* +@@ -38,46 +38,51 @@ static unsigned char mincore_page(struct + return present; + } + +-static long mincore_vma(struct vm_area_struct * vma, +- unsigned long start, unsigned long end, unsigned char __user * vec) ++/* ++ * Do a chunk of "sys_mincore()". We've already checked ++ * all the arguments, we hold the mmap semaphore: we should ++ * just return the amount of info we're asked for. ++ */ ++static long do_mincore(unsigned long addr, unsigned char *vec, unsigned long pages) + { +- long error, i, remaining; +- unsigned char * tmp; +- +- error = -ENOMEM; +- if (!vma->vm_file) +- return error; +- +- start = ((start - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; +- if (end > vma->vm_end) +- end = vma->vm_end; +- end = ((end - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; +- +- error = -EAGAIN; +- tmp = (unsigned char *) __get_free_page(GFP_KERNEL); +- if (!tmp) +- return error; +- +- /* (end - start) is # of pages, and also # of bytes in "vec */ +- remaining = (end - start), ++ unsigned long i, nr, pgoff; ++ struct vm_area_struct *vma = find_vma(current->mm, addr); + +- error = 0; +- for (i = 0; remaining > 0; remaining -= PAGE_SIZE, i++) { +- int j = 0; +- long thispiece = (remaining < PAGE_SIZE) ? +- remaining : PAGE_SIZE; ++ /* ++ * find_vma() didn't find anything above us, or we're ++ * in an unmapped hole in the address space: ENOMEM. ++ */ ++ if (!vma || addr < vma->vm_start) ++ return -ENOMEM; + +- while (j < thispiece) +- tmp[j++] = mincore_page(vma, start++); ++ /* ++ * Ok, got it. But check whether it's a segment we support ++ * mincore() on. Right now, we don't do any anonymous mappings. ++ * ++ * FIXME: This is just stupid. And returning ENOMEM is ++ * stupid too. We should just look at the page tables. But ++ * this is what we've traditionally done, so we'll just ++ * continue doing it. ++ */ ++ if (!vma->vm_file) ++ return -ENOMEM; + +- if (copy_to_user(vec + PAGE_SIZE * i, tmp, thispiece)) { +- error = -EFAULT; +- break; +- } +- } ++ /* ++ * Calculate how many pages there are left in the vma, and ++ * what the pgoff is for our address. ++ */ ++ nr = (vma->vm_end - addr) >> PAGE_SHIFT; ++ if (nr > pages) ++ nr = pages; ++ ++ pgoff = (addr - vma->vm_start) >> PAGE_SHIFT; ++ pgoff += vma->vm_pgoff; ++ ++ /* And then we just fill the sucker in.. */ ++ for (i = 0 ; i < nr; i++, pgoff++) ++ vec[i] = mincore_page(vma, pgoff); + +- free_page((unsigned long) tmp); +- return error; ++ return nr; + } + + /* +@@ -107,82 +112,50 @@ static long mincore_vma(struct vm_area_s + asmlinkage long sys_mincore(unsigned long start, size_t len, + unsigned char __user * vec) + { +- int index = 0; +- unsigned long end, limit; +- struct vm_area_struct * vma; +- size_t max; +- int unmapped_error = 0; +- long error; ++ long retval; ++ unsigned long pages; ++ unsigned char *tmp; + +- /* check the arguments */ ++ /* Check the start address: needs to be page-aligned.. */ + if (start & ~PAGE_CACHE_MASK) +- goto einval; +- +- limit = TASK_SIZE; +- if (start >= limit) +- goto enomem; ++ return -EINVAL; + +- if (!len) +- return 0; ++ /* ..and we need to be passed a valid user-space range */ ++ if (!access_ok(VERIFY_READ, (void __user *) start, len)) ++ return -ENOMEM; + +- max = limit - start; +- len = PAGE_CACHE_ALIGN(len); +- if (len > max || !len) +- goto enomem; ++ /* This also avoids any overflows on PAGE_CACHE_ALIGN */ ++ pages = len >> PAGE_SHIFT; ++ pages += (len & ~PAGE_MASK) != 0; + +- end = start + len; ++ if (!access_ok(VERIFY_WRITE, vec, pages)) ++ return -EFAULT; + +- /* check the output buffer whilst holding the lock */ +- error = -EFAULT; +- down_read(¤t->mm->mmap_sem); +- +- if (!access_ok(VERIFY_WRITE, vec, len >> PAGE_SHIFT)) +- goto out; +- +- /* +- * If the interval [start,end) covers some unmapped address +- * ranges, just ignore them, but return -ENOMEM at the end. +- */ +- error = 0; ++ tmp = (void *) __get_free_page(GFP_USER); ++ if (!tmp) ++ return -EAGAIN; + +- vma = find_vma(current->mm, start); +- while (vma) { +- /* Here start < vma->vm_end. */ +- if (start < vma->vm_start) { +- unmapped_error = -ENOMEM; +- start = vma->vm_start; +- } ++ retval = 0; ++ while (pages) { ++ /* ++ * Do at most PAGE_SIZE entries per iteration, due to ++ * the temporary buffer size. ++ */ ++ down_read(¤t->mm->mmap_sem); ++ retval = do_mincore(start, tmp, min(pages, PAGE_SIZE)); ++ up_read(¤t->mm->mmap_sem); + +- /* Here vma->vm_start <= start < vma->vm_end. */ +- if (end <= vma->vm_end) { +- if (start < end) { +- error = mincore_vma(vma, start, end, +- &vec[index]); +- if (error) +- goto out; +- } +- error = unmapped_error; +- goto out; ++ if (retval <= 0) ++ break; ++ if (copy_to_user(vec, tmp, retval)) { ++ retval = -EFAULT; ++ break; + } +- +- /* Here vma->vm_start <= start < vma->vm_end < end. */ +- error = mincore_vma(vma, start, vma->vm_end, &vec[index]); +- if (error) +- goto out; +- index += (vma->vm_end - start) >> PAGE_CACHE_SHIFT; +- start = vma->vm_end; +- vma = vma->vm_next; ++ pages -= retval; ++ vec += retval; ++ start += retval << PAGE_SHIFT; ++ retval = 0; + } +- +- /* we found a hole in the area queried if we arrive here */ +- error = -ENOMEM; +- +-out: +- up_read(¤t->mm->mmap_sem); +- return error; +- +-einval: +- return -EINVAL; +-enomem: +- return -ENOMEM; ++ free_page((unsigned long) tmp); ++ return retval; + } diff --git a/releases/2.6.19.2/fix-oom-killing-of-swapoff.patch b/releases/2.6.19.2/fix-oom-killing-of-swapoff.patch new file mode 100644 index 00000000000..c711cda42f4 --- /dev/null +++ b/releases/2.6.19.2/fix-oom-killing-of-swapoff.patch @@ -0,0 +1,53 @@ +From stable-bounces@linux.kernel.org Fri Jan 5 16:57:46 2007 +Message-Id: <200701060037.l060bUhd013413@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 05 Jan 2007 16:37:03 -0800 +Cc: akpm@osdl.org, hugh@veritas.com, stable@kernel.org +Subject: fix OOM killing of swapoff + +From: Hugh Dickins + +These days, if you swapoff when there isn't enough memory, OOM killer gives +"BUG: scheduling while atomic" and the machine hangs: badness() needs to do +its PF_SWAPOFF return after the task_unlock (tasklist_lock is also held +here, so p isn't going to be freed: PF_SWAPOFF might get turned off at any +moment, but that doesn't really matter). + +Signed-off-by: Hugh Dickins +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + mm/oom_kill.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- linux-2.6.19.1.orig/mm/oom_kill.c ++++ linux-2.6.19.1/mm/oom_kill.c +@@ -61,12 +61,6 @@ unsigned long badness(struct task_struct + } + + /* +- * swapoff can easily use up all memory, so kill those first. +- */ +- if (p->flags & PF_SWAPOFF) +- return ULONG_MAX; +- +- /* + * The memory size of the process is the basis for the badness. + */ + points = mm->total_vm; +@@ -77,6 +71,12 @@ unsigned long badness(struct task_struct + task_unlock(p); + + /* ++ * swapoff can easily use up all memory, so kill those first. ++ */ ++ if (p->flags & PF_SWAPOFF) ++ return ULONG_MAX; ++ ++ /* + * Processes which fork a lot of child processes are likely + * a good choice. We add half the vmsize of the children if they + * have an own mm. This prevents forking servers to flood the diff --git a/releases/2.6.19.2/fix-reversed-logic-in-udp_get_port.patch b/releases/2.6.19.2/fix-reversed-logic-in-udp_get_port.patch new file mode 100644 index 00000000000..96656d5665b --- /dev/null +++ b/releases/2.6.19.2/fix-reversed-logic-in-udp_get_port.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Fri Dec 22 12:02:42 2006 +Date: Fri, 22 Dec 2006 11:56:21 -0800 (PST) +Message-Id: <20061222.115621.104034701.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: UDP: Fix reversed logic in udp_get_port() + +When this code was converted to use sk_for_each() the +logic for the "best hash chain length" code was reversed, +breaking everything. + +The original code was of the form: + + size = 0; + do { + if (++size >= best_size_so_far) + goto next; + } while ((sk = sk->next) != NULL); + best_size_so_far = size; + best = result; + next:; + +and this got converted into: + + sk_for_each(sk2, node, head) + if (++size < best_size_so_far) { + best_size_so_far = size; + best = result; + } + +Which does something very very different from the original. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- + net/ipv4/udp.c | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +--- linux-2.6.19.1.orig/net/ipv4/udp.c ++++ linux-2.6.19.1/net/ipv4/udp.c +@@ -167,11 +167,14 @@ int udp_get_port(struct sock *sk, unsign + goto gotit; + } + size = 0; +- sk_for_each(sk2, node, head) +- if (++size < best_size_so_far) { +- best_size_so_far = size; +- best = result; +- } ++ sk_for_each(sk2, node, head) { ++ if (++size >= best_size_so_far) ++ goto next; ++ } ++ best_size_so_far = size; ++ best = result; ++ next: ++ ; + } + result = best; + for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) { diff --git a/releases/2.6.19.2/fix-up-page_mkclean_one-virtual-caches-s390.patch b/releases/2.6.19.2/fix-up-page_mkclean_one-virtual-caches-s390.patch new file mode 100644 index 00000000000..08a212e817a --- /dev/null +++ b/releases/2.6.19.2/fix-up-page_mkclean_one-virtual-caches-s390.patch @@ -0,0 +1,66 @@ +From c2fda5fed81eea077363b285b66eafce20dfd45a Mon Sep 17 00:00:00 2001 +From: Peter Zijlstra +Date: Fri, 22 Dec 2006 14:25:52 +0100 +Subject: [PATCH] Fix up page_mkclean_one(): virtual caches, s390 + + - add flush_cache_page() for all those virtual indexed cache + architectures. + + - handle s390. + +Signed-off-by: Peter Zijlstra +Signed-off-by: Linus Torvalds +[chrisw: fold in d6e88e671ac1] +Signed-off-by: Chris Wright +--- + mm/rmap.c | 23 +++++++++++++---------- + 1 file changed, 13 insertions(+), 10 deletions(-) + +--- linux-2.6.19.1.orig/mm/rmap.c ++++ linux-2.6.19.1/mm/rmap.c +@@ -432,7 +432,7 @@ static int page_mkclean_one(struct page + { + struct mm_struct *mm = vma->vm_mm; + unsigned long address; +- pte_t *pte, entry; ++ pte_t *pte; + spinlock_t *ptl; + int ret = 0; + +@@ -444,17 +444,18 @@ static int page_mkclean_one(struct page + if (!pte) + goto out; + +- if (!pte_dirty(*pte) && !pte_write(*pte)) +- goto unlock; ++ if (pte_dirty(*pte) || pte_write(*pte)) { ++ pte_t entry; + +- entry = ptep_get_and_clear(mm, address, pte); +- entry = pte_mkclean(entry); +- entry = pte_wrprotect(entry); +- ptep_establish(vma, address, pte, entry); +- lazy_mmu_prot_update(entry); +- ret = 1; ++ flush_cache_page(vma, address, pte_pfn(*pte)); ++ entry = ptep_clear_flush(vma, address, pte); ++ entry = pte_wrprotect(entry); ++ entry = pte_mkclean(entry); ++ set_pte_at(mm, address, pte, entry); ++ lazy_mmu_prot_update(entry); ++ ret = 1; ++ } + +-unlock: + pte_unmap_unlock(pte, ptl); + out: + return ret; +@@ -489,6 +490,8 @@ int page_mkclean(struct page *page) + if (mapping) + ret = page_mkclean_file(mapping, page); + } ++ if (page_test_and_clear_dirty(page)) ++ ret = 1; + + return ret; + } diff --git a/releases/2.6.19.2/handle-ext3-directory-corruption-better.patch b/releases/2.6.19.2/handle-ext3-directory-corruption-better.patch new file mode 100644 index 00000000000..aaacd744bdb --- /dev/null +++ b/releases/2.6.19.2/handle-ext3-directory-corruption-better.patch @@ -0,0 +1,89 @@ +From stable-bounces@linux.kernel.org Sat Dec 30 15:27:45 2006 +Message-ID: <4596F49F.4080406@gentoo.org> +Date: Sat, 30 Dec 2006 18:22:07 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: sandeen@redhat.com +Subject: handle ext3 directory corruption better (CVE-2006-6053) + +From: Eric Sandeen + +I've been using Steve Grubb's purely evil "fsfuzzer" tool, at +http://people.redhat.com/sgrubb/files/fsfuzzer-0.4.tar.gz + +Basically it makes a filesystem, splats some random bits over it, then +tries to mount it and do some simple filesystem actions. + +At best, the filesystem catches the corruption gracefully. At worst, +things spin out of control. + +As you might guess, we found a couple places in ext3 where things spin out +of control :) + +First, we had a corrupted directory that was never checked for +consistency... it was corrupt, and pointed to another bad "entry" of +length 0. The for() loop looped forever, since the length of +ext3_next_entry(de) was 0, and we kept looking at the same pointer over and +over and over and over... I modeled this check and subsequent action on +what is done for other directory types in ext3_readdir... + +(adding this check adds some computational expense; I am testing a followup +patch to reduce the number of times we check and re-check these directory +entries, in all cases. Thanks for the idea, Andreas). + +Next we had a root directory inode which had a corrupted size, claimed to +be > 200M on a 4M filesystem. There was only really 1 block in the +directory, but because the size was so large, readdir kept coming back for +more, spewing thousands of printk's along the way. + +Per Andreas' suggestion, if we're in this read error condition and we're +trying to read an offset which is greater than i_blocks worth of bytes, +stop trying, and break out of the loop. + +With these two changes fsfuzz test survives quite well on ext3. + +Signed-off-by: Eric Sandeen +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- +Date: Thu, 7 Dec 2006 04:36:26 +0000 (-0800) +Subject: [PATCH] handle ext3 directory corruption better +X-Git-Tag: v2.6.20-rc1 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=40b851348fe9bf49c26025b34261d25142269b60 + + fs/ext3/dir.c | 3 +++ + fs/ext3/namei.c | 9 +++++++++ + 2 files changed, 12 insertions(+) + +--- linux-2.6.19.1.orig/fs/ext3/dir.c ++++ linux-2.6.19.1/fs/ext3/dir.c +@@ -154,6 +154,9 @@ static int ext3_readdir(struct file * fi + ext3_error (sb, "ext3_readdir", + "directory #%lu contains a hole at offset %lu", + inode->i_ino, (unsigned long)filp->f_pos); ++ /* corrupt size? Maybe no more blocks to read */ ++ if (filp->f_pos > inode->i_blocks << 9) ++ break; + filp->f_pos += sb->s_blocksize - offset; + continue; + } +--- linux-2.6.19.1.orig/fs/ext3/namei.c ++++ linux-2.6.19.1/fs/ext3/namei.c +@@ -552,6 +552,15 @@ static int htree_dirblock_to_tree(struct + dir->i_sb->s_blocksize - + EXT3_DIR_REC_LEN(0)); + for (; de < top; de = ext3_next_entry(de)) { ++ if (!ext3_check_dir_entry("htree_dirblock_to_tree", dir, de, bh, ++ (block<i_sb)) ++ +((char *)de - bh->b_data))) { ++ /* On error, skip the f_pos to the next block. */ ++ dir_file->f_pos = (dir_file->f_pos | ++ (dir->i_sb->s_blocksize - 1)) + 1; ++ brelse (bh); ++ return count; ++ } + ext3fs_dirhash(de->name, de->name_len, hinfo); + if ((hinfo->hash < start_hash) || + ((hinfo->hash == start_hash) && diff --git a/releases/2.6.19.2/i2c-fix-broken-ds1337-initialization.patch b/releases/2.6.19.2/i2c-fix-broken-ds1337-initialization.patch new file mode 100644 index 00000000000..60f6a2246cf --- /dev/null +++ b/releases/2.6.19.2/i2c-fix-broken-ds1337-initialization.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Tue Dec 19 23:40:57 2006 +Date: Wed, 20 Dec 2006 08:34:43 +0100 +From: Jean Delvare +To: stable@kernel.org +Message-Id: <20061220083443.45e488cb.khali@linux-fr.org> +Cc: Dirk Eibach , Adrian Bunk +Subject: i2c: fix broken ds1337 initialization + +From: Dirk Eibach + +On a custom board with ds1337 RTC I found that upgrade from 2.6.15 to +2.6.18 broke RTC support. + +The main problem are changes to ds1337_init_client(). +When a ds1337 recognizes a problem (e.g. power or clock failure) bit 7 +in status register is set. This has to be reset by writing 0 to status +register. But since there are only 16 byte written to the chip and the +first byte is interpreted as an address, the status register (which is +the 16th) is never written. +The other problem is, that initializing all registers to zero is not +valid for day, date and month register. Funny enough this is checked by +ds1337_detect(), which depends on this values not being zero. So then +treated by ds1337_init_client() the ds1337 is not detected anymore, +whereas the failure bit in the status register is still set. + +Broken by commit f9e8957937ebf60d22732a5ca9130f48a7603f60 (2.6.16-rc1, +2006-01-06). This fix is in Linus' tree since 2.6.20-rc1 (commit +763d9c046a2e511ec090a8986d3f85edf7448e7e). + +Signed-off-by: Dirk Stieler +Signed-off-by: Dirk Eibach +Signed-off-by: Jean Delvare +Signed-off-by: Chris Wright +--- + drivers/i2c/chips/ds1337.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/i2c/chips/ds1337.c ++++ linux-2.6.19.1/drivers/i2c/chips/ds1337.c +@@ -347,13 +347,19 @@ static void ds1337_init_client(struct i2 + + if ((status & 0x80) || (control & 0x80)) { + /* RTC not running */ +- u8 buf[16]; ++ u8 buf[1+16]; /* First byte is interpreted as address */ + struct i2c_msg msg[1]; + + dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__); + + /* Initialize all, including STATUS and CONTROL to zero */ + memset(buf, 0, sizeof(buf)); ++ ++ /* Write valid values in the date/time registers */ ++ buf[1+DS1337_REG_DAY] = 1; ++ buf[1+DS1337_REG_DATE] = 1; ++ buf[1+DS1337_REG_MONTH] = 1; ++ + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].len = sizeof(buf); diff --git a/releases/2.6.19.2/i386-cpu-hotplug-broken-with-2gb-vmsplit.patch b/releases/2.6.19.2/i386-cpu-hotplug-broken-with-2gb-vmsplit.patch new file mode 100644 index 00000000000..6f247fb2141 --- /dev/null +++ b/releases/2.6.19.2/i386-cpu-hotplug-broken-with-2gb-vmsplit.patch @@ -0,0 +1,30 @@ +From stable-bounces@linux.kernel.org Sat Dec 23 18:48:39 2006 +Date: Sat, 23 Dec 2006 21:39:08 -0500 +From: Chuck Ebbert <76306.1226@compuserve.com> +To: linux-stable +Message-ID: <200612232141_MC3-1-D628-F7DD@compuserve.com> +Content-Disposition: inline +Cc: Shaohua Li +Subject: [stable] [stable patch] i386: CPU hotplug broken with 2GB VMSPLIT + +From: Shaohua Li + +In VMSPLIT mode, kernel PGD might have more entries than user space + +Signed-off-by: Shaohua Li +Signed-off-by: Chris Wright +--- + arch/i386/kernel/smpboot.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/arch/i386/kernel/smpboot.c ++++ linux-2.6.19.1/arch/i386/kernel/smpboot.c +@@ -1095,7 +1095,7 @@ static int __cpuinit __smp_prepare_cpu(i + + /* init low mem mapping */ + clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, +- KERNEL_PGD_PTRS); ++ min_t(unsigned long, KERNEL_PGD_PTRS, USER_PGD_PTRS)); + flush_tlb_all(); + schedule_work(&task); + wait_for_completion(&done); diff --git a/releases/2.6.19.2/ib-srp-fix-fmr-mapping-for-32-bit-kernels-and-addresses-above-4g.patch b/releases/2.6.19.2/ib-srp-fix-fmr-mapping-for-32-bit-kernels-and-addresses-above-4g.patch new file mode 100644 index 00000000000..555e8e21752 --- /dev/null +++ b/releases/2.6.19.2/ib-srp-fix-fmr-mapping-for-32-bit-kernels-and-addresses-above-4g.patch @@ -0,0 +1,51 @@ +From stable-bounces@linux.kernel.org Fri Dec 15 21:04:20 2006 +To: stable@kernel.org +From: Roland Dreier +Date: Fri, 15 Dec 2006 20:58:14 -0800 +Message-ID: +Subject: IB/srp: Fix FMR mapping for 32-bit kernels and addresses above 4G + +struct srp_device.fmr_page_mask was unsigned long, which means that +the top part of addresses above 4G was being chopped off on 32-bit +architectures. Of course nothing good happens when data from SRP +targets is DMAed to the wrong place. + +Fix this by changing fmr_page_mask to u64, to match the addresses +actually used by IB devices. + +Thanks to Brian Cain and David McMillen + for help diagnosing the bug and testing +the fix. + +Signed-off-by: Roland Dreier +Signed-off-by: Chris Wright +--- +I just asked Linus to pull this. It fixes nasty corruption/crash +problems on 32-bit systems with > 4G of memory. + + drivers/infiniband/ulp/srp/ib_srp.c | 2 +- + drivers/infiniband/ulp/srp/ib_srp.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/drivers/infiniband/ulp/srp/ib_srp.c ++++ linux-2.6.19.1/drivers/infiniband/ulp/srp/ib_srp.c +@@ -1879,7 +1879,7 @@ static void srp_add_one(struct ib_device + */ + srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1); + srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift; +- srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1); ++ srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1); + + INIT_LIST_HEAD(&srp_dev->dev_list); + +--- linux-2.6.19.1.orig/drivers/infiniband/ulp/srp/ib_srp.h ++++ linux-2.6.19.1/drivers/infiniband/ulp/srp/ib_srp.h +@@ -87,7 +87,7 @@ struct srp_device { + struct ib_fmr_pool *fmr_pool; + int fmr_page_shift; + int fmr_page_size; +- unsigned long fmr_page_mask; ++ u64 fmr_page_mask; + }; + + struct srp_host { diff --git a/releases/2.6.19.2/ieee1394-ohci1394-add-ppc_pmac-platform-code-to-driver-probe.patch b/releases/2.6.19.2/ieee1394-ohci1394-add-ppc_pmac-platform-code-to-driver-probe.patch new file mode 100644 index 00000000000..4f7d143887e --- /dev/null +++ b/releases/2.6.19.2/ieee1394-ohci1394-add-ppc_pmac-platform-code-to-driver-probe.patch @@ -0,0 +1,64 @@ +From stable-bounces@linux.kernel.org Tue Dec 12 20:05:58 2006 +Message-ID: <457F7AD0.3030005@gentoo.org> +Date: Tue, 12 Dec 2006 23:00:16 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: stefanr@s5r6.in-berlin.de +Subject: ieee1394: ohci1394: add PPC_PMAC platform code to driver probe + +From: Stefan Richter + +Fixes http://bugzilla.kernel.org/show_bug.cgi?id=7431 +iBook G3 threw a machine check exception and put the display backlight +to full brightness after ohci1394 was unloaded and reloaded. + +Signed-off-by: Stefan Richter +[dsd@gentoo.org: also added missing if condition, commit + 63cca59e89892497e95e1e9c7156d3345fb7e2e8] +Signed-off-by: Daniel Drake +Acked-by: Stefan Richter +Signed-off-by: Chris Wright +--- +It fixes a kernel oops which occurs when the ohci1394 driver is reloaded on PPC +http://bugs.gentoo.org/154851 + + drivers/ieee1394/ohci1394.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +--- linux-2.6.19.1.orig/drivers/ieee1394/ohci1394.c ++++ linux-2.6.19.1/drivers/ieee1394/ohci1394.c +@@ -3217,6 +3217,19 @@ static int __devinit ohci1394_pci_probe( + struct ti_ohci *ohci; /* shortcut to currently handled device */ + resource_size_t ohci_base; + ++#ifdef CONFIG_PPC_PMAC ++ /* Necessary on some machines if ohci1394 was loaded/ unloaded before */ ++ if (machine_is(powermac)) { ++ struct device_node *of_node = pci_device_to_OF_node(dev); ++ ++ if (of_node) { ++ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node, ++ 0, 1); ++ pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 1); ++ } ++ } ++#endif /* CONFIG_PPC_PMAC */ ++ + if (pci_enable_device(dev)) + FAIL(-ENXIO, "Failed to enable OHCI hardware"); + pci_set_master(dev); +@@ -3505,11 +3518,9 @@ static void ohci1394_pci_remove(struct p + #endif + + #ifdef CONFIG_PPC_PMAC +- /* On UniNorth, power down the cable and turn off the chip +- * clock when the module is removed to save power on +- * laptops. Turning it back ON is done by the arch code when +- * pci_enable_device() is called */ +- { ++ /* On UniNorth, power down the cable and turn off the chip clock ++ * to save power on laptops */ ++ if (machine_is(powermac)) { + struct device_node* of_node; + + of_node = pci_device_to_OF_node(ohci->dev); diff --git a/releases/2.6.19.2/ieee80211softmac-fix-mutex_lock-at-exit-of-ieee80211_softmac_get_genie.patch b/releases/2.6.19.2/ieee80211softmac-fix-mutex_lock-at-exit-of-ieee80211_softmac_get_genie.patch new file mode 100644 index 00000000000..4fab8db827a --- /dev/null +++ b/releases/2.6.19.2/ieee80211softmac-fix-mutex_lock-at-exit-of-ieee80211_softmac_get_genie.patch @@ -0,0 +1,32 @@ +From stable-bounces@linux.kernel.org Sun Dec 10 09:45:56 2006 +From: Michael Buesch +To: stable@kernel.org +Date: Sun, 10 Dec 2006 18:39:28 +0100 +Message-Id: <200612101839.28687.mb@bu3sch.de> +Cc: Andrew Morton , Johannes Berg , "John W. Linville" , dsd@gentoo.org +Subject: ieee80211softmac: Fix mutex_lock at exit of ieee80211_softmac_get_genie + +From: Ulrich Kunitz + +ieee80211softmac_wx_get_genie locks the associnfo mutex at +function exit. This patch fixes it. The patch is against Linus' +tree (commit af1713e0). + +Signed-off-by: Ulrich Kunitz +Signed-off-by: Michael Buesch +Signed-off-by: Chris Wright +--- + net/ieee80211/softmac/ieee80211softmac_wx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/net/ieee80211/softmac/ieee80211softmac_wx.c ++++ linux-2.6.19.1/net/ieee80211/softmac/ieee80211softmac_wx.c +@@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net + err = -E2BIG; + } + spin_unlock_irqrestore(&mac->lock, flags); +- mutex_lock(&mac->associnfo.mutex); ++ mutex_unlock(&mac->associnfo.mutex); + + return err; + } diff --git a/releases/2.6.19.2/ipv4-ipv6-fix-inet-6-device-initialization-order.patch b/releases/2.6.19.2/ipv4-ipv6-fix-inet-6-device-initialization-order.patch new file mode 100644 index 00000000000..e38803e5559 --- /dev/null +++ b/releases/2.6.19.2/ipv4-ipv6-fix-inet-6-device-initialization-order.patch @@ -0,0 +1,68 @@ +From stable-bounces@linux.kernel.org Thu Jan 4 17:14:44 2007 +Date: Thu, 04 Jan 2007 17:07:34 -0800 (PST) +Message-Id: <20070104.170734.94556619.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: IPV4/IPV6: Fix inet{,6} device initialization order. + +From: David L Stevens + +It is important that we only assign dev->ip{,6}_ptr +only after all portions of the inet{,6} are setup. + +Otherwise we can receive packets before the multicast +spinlocks et al. are initialized. + +Signed-off-by: David L Stevens +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- +commit 30c4cf577fb5b68c16e5750d6bdbd7072e42b279 + + net/ipv4/devinet.c | 5 +++-- + net/ipv6/addrconf.c | 4 ++-- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- linux-2.6.19.1.orig/net/ipv4/devinet.c ++++ linux-2.6.19.1/net/ipv4/devinet.c +@@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct ne + NET_IPV4_NEIGH, "ipv4", NULL, NULL); + #endif + +- /* Account for reference dev->ip_ptr */ ++ /* Account for reference dev->ip_ptr (below) */ + in_dev_hold(in_dev); +- rcu_assign_pointer(dev->ip_ptr, in_dev); + + #ifdef CONFIG_SYSCTL + devinet_sysctl_register(in_dev, &in_dev->cnf); +@@ -176,6 +175,8 @@ struct in_device *inetdev_init(struct ne + if (dev->flags & IFF_UP) + ip_mc_up(in_dev); + out: ++ /* we can receive as soon as ip_ptr is set -- do this last */ ++ rcu_assign_pointer(dev->ip_ptr, in_dev); + return in_dev; + out_kfree: + kfree(in_dev); +--- linux-2.6.19.1.orig/net/ipv6/addrconf.c ++++ linux-2.6.19.1/net/ipv6/addrconf.c +@@ -413,8 +413,6 @@ static struct inet6_dev * ipv6_add_dev(s + if (netif_carrier_ok(dev)) + ndev->if_flags |= IF_READY; + +- /* protected by rtnl_lock */ +- rcu_assign_pointer(dev->ip6_ptr, ndev); + + ipv6_mc_init_dev(ndev); + ndev->tstamp = jiffies; +@@ -425,6 +423,8 @@ static struct inet6_dev * ipv6_add_dev(s + NULL); + addrconf_sysctl_register(ndev, &ndev->cnf); + #endif ++ /* protected by rtnl_lock */ ++ rcu_assign_pointer(dev->ip6_ptr, ndev); + return ndev; + } + diff --git a/releases/2.6.19.2/kbuild-don-t-put-temp-files-in-source.patch b/releases/2.6.19.2/kbuild-don-t-put-temp-files-in-source.patch new file mode 100644 index 00000000000..15afd3efc50 --- /dev/null +++ b/releases/2.6.19.2/kbuild-don-t-put-temp-files-in-source.patch @@ -0,0 +1,73 @@ +From stable-bounces@linux.kernel.org Tue Dec 12 20:10:02 2006 +Message-ID: <457F7BC3.3020508@gentoo.org> +Date: Tue, 12 Dec 2006 23:04:19 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: zippel@linux-m68k.org +Subject: kbuild: don't put temp files in source + +From: Roman Zippel + +The as-instr/ld-option need to create temporary files, but create them in the +output directory, when compiling external modules. Reformat them a bit and +use $(CC) instead of $(AS) as the former is used by kbuild to assemble files. + +Signed-off-by: Roman Zippel +Cc: Andi Kleen +Cc: Jan Beulich +Cc: Sam Ravnborg +Cc: +Cc: Horst Schirmeier +Cc: Daniel Drake +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright +--- +It fixes building of external modules in a sandboxed environment. +http://bugs.gentoo.org/149307 + + scripts/Kbuild.include | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- linux-2.6.19.1.orig/scripts/Kbuild.include ++++ linux-2.6.19.1/scripts/Kbuild.include +@@ -56,6 +56,9 @@ endef + # gcc support functions + # See documentation in Documentation/kbuild/makefiles.txt + ++# output directory for tests below ++TMPOUT := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/) ++ + # as-option + # Usage: cflags-y += $(call as-option, -Wa$(comma)-isa=foo,) + +@@ -66,9 +69,11 @@ as-option = $(shell if $(CC) $(CFLAGS) $ + # as-instr + # Usage: cflags-y += $(call as-instr, instr, option1, option2) + +-as-instr = $(shell if echo -e "$(1)" | $(AS) >/dev/null 2>&1 -W -Z -o astest$$$$.out ; \ +- then echo "$(2)"; else echo "$(3)"; fi; \ +- rm -f astest$$$$.out) ++as-instr = $(shell if echo -e "$(1)" | \ ++ $(CC) $(AFLAGS) -c -xassembler - \ ++ -o $(TMPOUT)astest$$$$.out > /dev/null 2>&1; \ ++ then rm $(TMPOUT)astest$$$$.out; echo "$(2)"; \ ++ else echo "$(3)"; fi) + + # cc-option + # Usage: cflags-y += $(call cc-option, -march=winchip-c6, -march=i586) +@@ -97,10 +102,10 @@ cc-ifversion = $(shell if [ $(call cc-ve + + # ld-option + # Usage: ldflags += $(call ld-option, -Wl$(comma)--hash-style=both) +-ld-option = $(shell if $(CC) $(1) \ +- -nostdlib -o ldtest$$$$.out -xc /dev/null \ +- > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi; \ +- rm -f ldtest$$$$.out) ++ld-option = $(shell if $(CC) $(1) -nostdlib -xc /dev/null \ ++ -o $(TMPOUT)ldtest$$$$.out > /dev/null 2>&1; \ ++ then rm $(TMPOUT)ldtest$$$$.out; echo "$(1)"; \ ++ else echo "$(2)"; fi) + + ### + # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.build obj= diff --git a/releases/2.6.19.2/libata-handle-0xff-status-properly.patch b/releases/2.6.19.2/libata-handle-0xff-status-properly.patch new file mode 100644 index 00000000000..1c1368e57f1 --- /dev/null +++ b/releases/2.6.19.2/libata-handle-0xff-status-properly.patch @@ -0,0 +1,139 @@ +From stable-bounces@linux.kernel.org Tue Dec 12 20:04:28 2006 +Message-ID: <457F7A78.6090102@gentoo.org> +Date: Tue, 12 Dec 2006 22:58:48 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: htejun@gmail.com +Subject: libata: handle 0xff status properly + +From: Tejun Heo + +libata waits for !BSY even when the status register reports 0xff. +This causes long boot delays when D8 isn't pulled down properly. This +patch does the followings. + +* don't wait if status register is 0xff in all wait functions + +* make ata_busy_sleep() return 0 on success and -errno on failure. + -ENODEV is returned on 0xff status and -EBUSY on other failures. + +* make ata_bus_softreset() succeed on 0xff status. 0xff status is not + reset failure. It indicates no device. This removes unnecessary + retries on such ports. Note that the code change assumes unoccupied + port reporting 0xff status does not produce valid device signature. + +Signed-off-by: Tejun Heo +Cc: Joe Jin +Signed-off-by: Jeff Garzik +Signed-off-by: Chris Wright +--- +It fixes a long delay during booting for some hardware. +http://bugs.gentoo.org/157326 + + drivers/ata/libata-core.c | 30 ++++++++++++++++++------------ + include/linux/libata.h | 9 ++++----- + 2 files changed, 22 insertions(+), 17 deletions(-) + +--- linux-2.6.19.1.orig/drivers/ata/libata-core.c ++++ linux-2.6.19.1/drivers/ata/libata-core.c +@@ -2325,11 +2325,14 @@ static inline void ata_tf_to_host(struct + * Sleep until ATA Status register bit BSY clears, + * or a timeout occurs. + * +- * LOCKING: None. ++ * LOCKING: ++ * Kernel thread context (may sleep). ++ * ++ * RETURNS: ++ * 0 on success, -errno otherwise. + */ +- +-unsigned int ata_busy_sleep (struct ata_port *ap, +- unsigned long tmout_pat, unsigned long tmout) ++int ata_busy_sleep(struct ata_port *ap, ++ unsigned long tmout_pat, unsigned long tmout) + { + unsigned long timer_start, timeout; + u8 status; +@@ -2337,27 +2340,32 @@ unsigned int ata_busy_sleep (struct ata_ + status = ata_busy_wait(ap, ATA_BUSY, 300); + timer_start = jiffies; + timeout = timer_start + tmout_pat; +- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { ++ while (status != 0xff && (status & ATA_BUSY) && ++ time_before(jiffies, timeout)) { + msleep(50); + status = ata_busy_wait(ap, ATA_BUSY, 3); + } + +- if (status & ATA_BUSY) ++ if (status != 0xff && (status & ATA_BUSY)) + ata_port_printk(ap, KERN_WARNING, + "port is slow to respond, please be patient " + "(Status 0x%x)\n", status); + + timeout = timer_start + tmout; +- while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { ++ while (status != 0xff && (status & ATA_BUSY) && ++ time_before(jiffies, timeout)) { + msleep(50); + status = ata_chk_status(ap); + } + ++ if (status == 0xff) ++ return -ENODEV; ++ + if (status & ATA_BUSY) { + ata_port_printk(ap, KERN_ERR, "port failed to respond " + "(%lu secs, Status 0x%x)\n", + tmout / HZ, status); +- return 1; ++ return -EBUSY; + } + + return 0; +@@ -2448,10 +2456,8 @@ static unsigned int ata_bus_softreset(st + * the bus shows 0xFF because the odd clown forgets the D7 + * pulldown resistor. + */ +- if (ata_check_status(ap) == 0xFF) { +- ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n"); +- return AC_ERR_OTHER; +- } ++ if (ata_check_status(ap) == 0xFF) ++ return 0; + + ata_bus_post_reset(ap, devmask); + +--- linux-2.6.19.1.orig/include/linux/libata.h ++++ linux-2.6.19.1/include/linux/libata.h +@@ -744,9 +744,8 @@ extern int ata_scsi_device_suspend(struc + extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); + extern void ata_host_resume(struct ata_host *host); + extern int ata_ratelimit(void); +-extern unsigned int ata_busy_sleep(struct ata_port *ap, +- unsigned long timeout_pat, +- unsigned long timeout); ++extern int ata_busy_sleep(struct ata_port *ap, ++ unsigned long timeout_pat, unsigned long timeout); + extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), + void *data, unsigned long delay); + extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, +@@ -1061,7 +1060,7 @@ static inline u8 ata_busy_wait(struct at + udelay(10); + status = ata_chk_status(ap); + max--; +- } while ((status & bits) && (max > 0)); ++ } while (status != 0xff && (status & bits) && (max > 0)); + + return status; + } +@@ -1082,7 +1081,7 @@ static inline u8 ata_wait_idle(struct at + { + u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + +- if (status & (ATA_BUSY | ATA_DRQ)) { ++ if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) { + unsigned long l = ap->ioaddr.status_addr; + if (ata_msg_warn(ap)) + printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", diff --git a/releases/2.6.19.2/net-don-t-export-linux-random.h-outside-__kernel__.patch b/releases/2.6.19.2/net-don-t-export-linux-random.h-outside-__kernel__.patch new file mode 100644 index 00000000000..4265b864617 --- /dev/null +++ b/releases/2.6.19.2/net-don-t-export-linux-random.h-outside-__kernel__.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Tue Jan 2 00:14:53 2007 +Date: Tue, 02 Jan 2007 00:07:50 -0800 (PST) +Message-Id: <20070102.000750.115910105.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: NET: Don't export linux/random.h outside __KERNEL__ + +From: David Woodhouse + +Don't add it there please; add it lower down inside the existing #ifdef +__KERNEL__. You just made the _userspace_ net.h include random.h, which +then fails to compile unless was already included. + +Signed-off-by: David Woodhouse +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- + include/linux/net.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/include/linux/net.h ++++ linux-2.6.19.1/include/linux/net.h +@@ -19,7 +19,6 @@ + #define _LINUX_NET_H + + #include +-#include + #include + + struct poll_table_struct; +@@ -57,6 +56,7 @@ typedef enum { + + #ifdef __KERNEL__ + #include ++#include + + #define SOCK_ASYNC_NOSPACE 0 + #define SOCK_ASYNC_WAITDATA 1 diff --git a/releases/2.6.19.2/netlabel-correctly-fill-in-unused-cipsov4-level-and-category-mappings.patch b/releases/2.6.19.2/netlabel-correctly-fill-in-unused-cipsov4-level-and-category-mappings.patch new file mode 100644 index 00000000000..65b5db0ab7a --- /dev/null +++ b/releases/2.6.19.2/netlabel-correctly-fill-in-unused-cipsov4-level-and-category-mappings.patch @@ -0,0 +1,57 @@ +From stable-bounces@linux.kernel.org Fri Jan 5 11:35:00 2007 +From: "Paul Moore" +Message-Id: <20061218180735.795797000@hp.com> +Date: Mon, 18 Dec 2006 13:07:29 -0500 +To: stable@kernel.org +Subject: NetLabel: correctly fill in unused CIPSOv4 level and category mappings + +From: Paul Moore + +Back when the original NetLabel patches were being changed to use Netlink +attributes correctly some code was accidentially dropped which set all of the +undefined CIPSOv4 level and category mappings to a sentinel value. The result +is the mappings data in the kernel contains bogus mappings which always map to +zero. Having level and category mappings that map to zero could result in the +kernel assigning incorrect security attributes to packets. + +This patch restores the old/correct behavior by initializing the mapping +data to the correct sentinel value. + +Signed-off-by: Paul Moore +Signed-off-by: Chris Wright +--- + net/netlabel/netlabel_cipso_v4.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- linux-2.6.19.1.orig/net/netlabel/netlabel_cipso_v4.c ++++ linux-2.6.19.1/net/netlabel/netlabel_cipso_v4.c +@@ -162,6 +162,7 @@ static int netlbl_cipsov4_add_std(struct + struct nlattr *nla_b; + int nla_a_rem; + int nla_b_rem; ++ u32 iter; + + if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] || + !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST]) +@@ -223,6 +224,10 @@ static int netlbl_cipsov4_add_std(struct + ret_val = -ENOMEM; + goto add_std_failure; + } ++ for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++) ++ doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL; ++ for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++) ++ doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL; + nla_for_each_nested(nla_a, + info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], + nla_a_rem) +@@ -296,6 +301,10 @@ static int netlbl_cipsov4_add_std(struct + ret_val = -ENOMEM; + goto add_std_failure; + } ++ for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++) ++ doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT; ++ for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++) ++ doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT; + nla_for_each_nested(nla_a, + info->attrs[NLBL_CIPSOV4_A_MLSCATLST], + nla_a_rem) diff --git a/releases/2.6.19.2/pktgen-fix-module-load-unload-races.patch b/releases/2.6.19.2/pktgen-fix-module-load-unload-races.patch new file mode 100644 index 00000000000..87003c8ca6a --- /dev/null +++ b/releases/2.6.19.2/pktgen-fix-module-load-unload-races.patch @@ -0,0 +1,91 @@ +From stable-bounces@linux.kernel.org Mon Jan 1 21:11:24 2007 +Date: Mon, 01 Jan 2007 21:04:19 -0800 (PST) +Message-Id: <20070101.210419.104643422.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: PKTGEN: Fix module load/unload races. + +From: Robert Olsson + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- + net/core/pktgen.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/net/core/pktgen.c ++++ linux-2.6.19.1/net/core/pktgen.c +@@ -147,6 +147,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -206,6 +207,11 @@ static struct proc_dir_entry *pg_proc_di + #define VLAN_TAG_SIZE(x) ((x)->vlan_id == 0xffff ? 0 : 4) + #define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4) + ++struct pktgen_thread_info { ++ struct pktgen_thread *t; ++ struct completion *c; ++}; ++ + struct flow_state { + __u32 cur_daddr; + int count; +@@ -3264,10 +3270,11 @@ out:; + * Main loop of the thread goes here + */ + +-static void pktgen_thread_worker(struct pktgen_thread *t) ++static void pktgen_thread_worker(struct pktgen_thread_info *info) + { + DEFINE_WAIT(wait); + struct pktgen_dev *pkt_dev = NULL; ++ struct pktgen_thread *t = info->t; + int cpu = t->cpu; + sigset_t tmpsig; + u32 max_before_softirq; +@@ -3307,6 +3314,8 @@ static void pktgen_thread_worker(struct + __set_current_state(TASK_INTERRUPTIBLE); + mb(); + ++ complete(info->c); ++ + while (1) { + + __set_current_state(TASK_RUNNING); +@@ -3518,6 +3527,8 @@ static struct pktgen_thread *__init pktg + static int __init pktgen_create_thread(const char *name, int cpu) + { + int err; ++ struct pktgen_thread_info info; ++ struct completion started; + struct pktgen_thread *t = NULL; + struct proc_dir_entry *pe; + +@@ -3558,7 +3569,11 @@ static int __init pktgen_create_thread(c + + t->removed = 0; + +- err = kernel_thread((void *)pktgen_thread_worker, (void *)t, ++ init_completion(&started); ++ info.t = t; ++ info.c = &started; ++ ++ err = kernel_thread((void *)pktgen_thread_worker, (void *)&info, + CLONE_FS | CLONE_FILES | CLONE_SIGHAND); + if (err < 0) { + printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu); +@@ -3568,6 +3583,7 @@ static int __init pktgen_create_thread(c + return err; + } + ++ wait_for_completion(&started); + return 0; + } + diff --git a/releases/2.6.19.2/ramfs-breaks-without-config_block.patch b/releases/2.6.19.2/ramfs-breaks-without-config_block.patch new file mode 100644 index 00000000000..712f98cb04b --- /dev/null +++ b/releases/2.6.19.2/ramfs-breaks-without-config_block.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Fri Dec 29 16:55:45 2006 +Message-Id: <200612300048.kBU0mhs0008126@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 29 Dec 2006 16:48:24 -0800 +Cc: akpm@osdl.org, dimitri.gorokhovik@free.fr, stable@kernel.org +Subject: ramfs breaks without CONFIG_BLOCK + +From: Dimitri Gorokhovik + +ramfs doesn't provide the .set_dirty_page a_op, and when the BLOCK layer is +not configured in, 'set_page_dirty' makes a call via a NULL pointer. + +Signed-off-by: Dimitri Gorokhovik +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + fs/ramfs/file-mmu.c | 4 +++- + fs/ramfs/file-nommu.c | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/fs/ramfs/file-mmu.c ++++ linux-2.6.19.1/fs/ramfs/file-mmu.c +@@ -25,11 +25,13 @@ + */ + + #include ++#include + + const struct address_space_operations ramfs_aops = { + .readpage = simple_readpage, + .prepare_write = simple_prepare_write, +- .commit_write = simple_commit_write ++ .commit_write = simple_commit_write, ++ .set_page_dirty = __set_page_dirty_nobuffers, + }; + + const struct file_operations ramfs_file_operations = { +--- linux-2.6.19.1.orig/fs/ramfs/file-nommu.c ++++ linux-2.6.19.1/fs/ramfs/file-nommu.c +@@ -11,6 +11,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -30,7 +31,8 @@ static int ramfs_nommu_setattr(struct de + const struct address_space_operations ramfs_aops = { + .readpage = simple_readpage, + .prepare_write = simple_prepare_write, +- .commit_write = simple_commit_write ++ .commit_write = simple_commit_write, ++ .set_page_dirty = __set_page_dirty_nobuffers, + }; + + const struct file_operations ramfs_file_operations = { diff --git a/releases/2.6.19.2/read_zero_pagealigned-locking-fix.patch b/releases/2.6.19.2/read_zero_pagealigned-locking-fix.patch new file mode 100644 index 00000000000..c09a43f8ad7 --- /dev/null +++ b/releases/2.6.19.2/read_zero_pagealigned-locking-fix.patch @@ -0,0 +1,149 @@ +From stable-bounces@linux.kernel.org Sun Dec 10 02:24:42 2006 +Message-Id: <200612101018.kBAAIiFj021055@shell0.pdx.osdl.net> +From: akpm@osdl.org +To: torvalds@osdl.org +Date: Sun, 10 Dec 2006 02:18:43 -0800 +Cc: akpm@osdl.org, hugh@veritas.com, Ramiro.Voicu@cern.ch, stable@kernel.org +Subject: read_zero_pagealigned() locking fix + +From: Hugh Dickins + +Ramiro Voicu hits the BUG_ON(!pte_none(*pte)) in zeromap_pte_range: kernel +bugzilla 7645. Right: read_zero_pagealigned uses down_read of mmap_sem, +but another thread's racing read of /dev/zero, or a normal fault, can +easily set that pte again, in between zap_page_range and zeromap_page_range +getting there. It's been wrong ever since 2.4.3. + +The simple fix is to use down_write instead, but that would serialize reads +of /dev/zero more than at present: perhaps some app would be badly +affected. So instead let zeromap_page_range return the error instead of +BUG_ON, and read_zero_pagealigned break to the slower clear_user loop in +that case - there's no need to optimize for it. + +Use -EEXIST for when a pte is found: BUG_ON in mmap_zero (the other user of +zeromap_page_range), though it really isn't interesting there. And since +mmap_zero wants -EAGAIN for out-of-memory, the zeromaps better return that +than -ENOMEM. + +Signed-off-by: Hugh Dickins +Cc: Ramiro Voicu: +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + drivers/char/mem.c | 12 ++++++++---- + mm/memory.c | 32 +++++++++++++++++++++----------- + 2 files changed, 29 insertions(+), 15 deletions(-) + +--- linux-2.6.19.1.orig/drivers/char/mem.c ++++ linux-2.6.19.1/drivers/char/mem.c +@@ -646,7 +646,8 @@ static inline size_t read_zero_pagealign + count = size; + + zap_page_range(vma, addr, count, NULL); +- zeromap_page_range(vma, addr, count, PAGE_COPY); ++ if (zeromap_page_range(vma, addr, count, PAGE_COPY)) ++ break; + + size -= count; + buf += count; +@@ -713,11 +714,14 @@ out: + + static int mmap_zero(struct file * file, struct vm_area_struct * vma) + { ++ int err; ++ + if (vma->vm_flags & VM_SHARED) + return shmem_zero_setup(vma); +- if (zeromap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start, vma->vm_page_prot)) +- return -EAGAIN; +- return 0; ++ err = zeromap_page_range(vma, vma->vm_start, ++ vma->vm_end - vma->vm_start, vma->vm_page_prot); ++ BUG_ON(err == -EEXIST); ++ return err; + } + #else /* CONFIG_MMU */ + static ssize_t read_zero(struct file * file, char * buf, +--- linux-2.6.19.1.orig/mm/memory.c ++++ linux-2.6.19.1/mm/memory.c +@@ -1110,23 +1110,29 @@ static int zeromap_pte_range(struct mm_s + { + pte_t *pte; + spinlock_t *ptl; ++ int err = 0; + + pte = pte_alloc_map_lock(mm, pmd, addr, &ptl); + if (!pte) +- return -ENOMEM; ++ return -EAGAIN; + arch_enter_lazy_mmu_mode(); + do { + struct page *page = ZERO_PAGE(addr); + pte_t zero_pte = pte_wrprotect(mk_pte(page, prot)); ++ ++ if (unlikely(!pte_none(*pte))) { ++ err = -EEXIST; ++ pte++; ++ break; ++ } + page_cache_get(page); + page_add_file_rmap(page); + inc_mm_counter(mm, file_rss); +- BUG_ON(!pte_none(*pte)); + set_pte_at(mm, addr, pte, zero_pte); + } while (pte++, addr += PAGE_SIZE, addr != end); + arch_leave_lazy_mmu_mode(); + pte_unmap_unlock(pte - 1, ptl); +- return 0; ++ return err; + } + + static inline int zeromap_pmd_range(struct mm_struct *mm, pud_t *pud, +@@ -1134,16 +1140,18 @@ static inline int zeromap_pmd_range(stru + { + pmd_t *pmd; + unsigned long next; ++ int err; + + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) +- return -ENOMEM; ++ return -EAGAIN; + do { + next = pmd_addr_end(addr, end); +- if (zeromap_pte_range(mm, pmd, addr, next, prot)) +- return -ENOMEM; ++ err = zeromap_pte_range(mm, pmd, addr, next, prot); ++ if (err) ++ break; + } while (pmd++, addr = next, addr != end); +- return 0; ++ return err; + } + + static inline int zeromap_pud_range(struct mm_struct *mm, pgd_t *pgd, +@@ -1151,16 +1159,18 @@ static inline int zeromap_pud_range(stru + { + pud_t *pud; + unsigned long next; ++ int err; + + pud = pud_alloc(mm, pgd, addr); + if (!pud) +- return -ENOMEM; ++ return -EAGAIN; + do { + next = pud_addr_end(addr, end); +- if (zeromap_pmd_range(mm, pud, addr, next, prot)) +- return -ENOMEM; ++ err = zeromap_pmd_range(mm, pud, addr, next, prot); ++ if (err) ++ break; + } while (pud++, addr = next, addr != end); +- return 0; ++ return err; + } + + int zeromap_page_range(struct vm_area_struct *vma, diff --git a/releases/2.6.19.2/revert-zd1211rw-removed-unneeded-packed-attributes.patch b/releases/2.6.19.2/revert-zd1211rw-removed-unneeded-packed-attributes.patch new file mode 100644 index 00000000000..f55203fbc52 --- /dev/null +++ b/releases/2.6.19.2/revert-zd1211rw-removed-unneeded-packed-attributes.patch @@ -0,0 +1,124 @@ +From stable-bounces@linux.kernel.org Tue Dec 12 20:02:04 2006 +Message-ID: <457F79E1.6010005@gentoo.org> +Date: Tue, 12 Dec 2006 22:56:17 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: linville@tuxdriver.com +Subject: Revert "[PATCH] zd1211rw: Removed unneeded packed attributes" + +From: John W. Linville + +This reverts commit 4e1bbd846d00a245dcf78b6b331d8a9afed8e6d7. + +Quoth Daniel Drake : + +"A user reported that commit 4e1bbd846d00a245dcf78b6b331d8a9afed8e6d7 +(Remove unneeded packed attributes) breaks the zd1211rw driver on ARM." + +Signed-off-by: John W. Linville +Signed-off-by: Chris Wright +--- + drivers/net/wireless/zd1211rw/zd_ieee80211.h | 2 +- + drivers/net/wireless/zd1211rw/zd_mac.c | 2 +- + drivers/net/wireless/zd1211rw/zd_mac.h | 4 ++-- + drivers/net/wireless/zd1211rw/zd_usb.h | 14 +++++++------- + 4 files changed, 11 insertions(+), 11 deletions(-) + +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_ieee80211.h ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_ieee80211.h +@@ -64,7 +64,7 @@ struct cck_plcp_header { + u8 service; + __le16 length; + __le16 crc16; +-}; ++} __attribute__((packed)); + + static inline u8 zd_cck_plcp_header_rate(const struct cck_plcp_header *header) + { +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.c ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.c +@@ -721,7 +721,7 @@ struct zd_rt_hdr { + u8 rt_rate; + u16 rt_channel; + u16 rt_chbitmask; +-}; ++} __attribute__((packed)); + + static void fill_rt_header(void *buffer, struct zd_mac *mac, + const struct ieee80211_rx_stats *stats, +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.h ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.h +@@ -82,7 +82,7 @@ struct zd_ctrlset { + struct rx_length_info { + __le16 length[3]; + __le16 tag; +-}; ++} __attribute__((packed)); + + #define RX_LENGTH_INFO_TAG 0x697e + +@@ -93,7 +93,7 @@ struct rx_status { + u8 signal_quality_ofdm; + u8 decryption_type; + u8 frame_status; +-}; ++} __attribute__((packed)); + + /* rx_status field decryption_type */ + #define ZD_RX_NO_WEP 0 +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_usb.h ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_usb.h +@@ -74,17 +74,17 @@ enum control_requests { + struct usb_req_read_regs { + __le16 id; + __le16 addr[0]; +-}; ++} __attribute__((packed)); + + struct reg_data { + __le16 addr; + __le16 value; +-}; ++} __attribute__((packed)); + + struct usb_req_write_regs { + __le16 id; + struct reg_data reg_writes[0]; +-}; ++} __attribute__((packed)); + + enum { + RF_IF_LE = 0x02, +@@ -101,7 +101,7 @@ struct usb_req_rfwrite { + /* RF2595: 24 */ + __le16 bit_values[0]; + /* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */ +-}; ++} __attribute__((packed)); + + /* USB interrupt */ + +@@ -118,12 +118,12 @@ enum usb_int_flags { + struct usb_int_header { + u8 type; /* must always be 1 */ + u8 id; +-}; ++} __attribute__((packed)); + + struct usb_int_regs { + struct usb_int_header hdr; + struct reg_data regs[0]; +-}; ++} __attribute__((packed)); + + struct usb_int_retry_fail { + struct usb_int_header hdr; +@@ -131,7 +131,7 @@ struct usb_int_retry_fail { + u8 _dummy; + u8 addr[ETH_ALEN]; + u8 ibss_wakeup_dest; +-}; ++} __attribute__((packed)); + + struct read_regs_int { + struct completion completion; diff --git a/releases/2.6.19.2/sched-fix-bad-missed-wakeups-in-the-i386-x86_64-ia64-acpi-and-apm-idle-code.patch b/releases/2.6.19.2/sched-fix-bad-missed-wakeups-in-the-i386-x86_64-ia64-acpi-and-apm-idle-code.patch new file mode 100644 index 00000000000..8198511f2e4 --- /dev/null +++ b/releases/2.6.19.2/sched-fix-bad-missed-wakeups-in-the-i386-x86_64-ia64-acpi-and-apm-idle-code.patch @@ -0,0 +1,224 @@ +From mingo@elte.hu Thu Dec 21 04:29:43 2006 +Date: Thu, 21 Dec 2006 13:20:30 +0100 +From: Ingo Molnar +To: Greg KH , Chris Wright , Adrian Bunk , stable@kernel.org +Subject: sched: fix bad missed wakeups in the i386, x86_64, ia64, ACPI and APM idle code +Message-ID: <20061221122030.GA10727@elte.hu> + +From: Ingo Molnar + +Fernando Lopez-Lezcano reported frequent scheduling latencies and audio +xruns starting at the 2.6.18-rt kernel, and those problems persisted all +until current -rt kernels. The latencies were serious and unjustified by +system load, often in the milliseconds range. + +After a patient and heroic multi-month effort of Fernando, where he +tested dozens of kernels, tried various configs, boot options, +test-patches of mine and provided latency traces of those incidents, the +following 'smoking gun' trace was captured by him: + + _------=> CPU# + / _-----=> irqs-off + | / _----=> need-resched + || / _---=> hardirq/softirq + ||| / _--=> preempt-depth + |||| / + ||||| delay + cmd pid ||||| time | caller + \ / ||||| \ | / + IRQ_19-1479 1D..1 0us : __trace_start_sched_wakeup (try_to_wake_up) + IRQ_19-1479 1D..1 0us : __trace_start_sched_wakeup <<...>-5856> (37 0) + IRQ_19-1479 1D..1 0us : __trace_start_sched_wakeup (c01262ba 0 0) + IRQ_19-1479 1D..1 0us : resched_task (try_to_wake_up) + IRQ_19-1479 1D..1 0us : __spin_unlock_irqrestore (try_to_wake_up) + ... + -0 1...1 11us!: default_idle (cpu_idle) + ... + -0 0Dn.1 602us : smp_apic_timer_interrupt (c0103baf 1 0) + ... + <...>-5856 0D..2 618us : __switch_to (__schedule) + <...>-5856 0D..2 618us : __schedule <-0> (20 162) + <...>-5856 0D..2 619us : __spin_unlock_irq (__schedule) + <...>-5856 0...1 619us : trace_stop_sched_switched (__schedule) + <...>-5856 0D..1 619us : trace_stop_sched_switched <<...>-5856> (37 0) + +what is visible in this trace is that CPU#1 ran try_to_wake_up() for +PID:5856, it placed PID:5856 on CPU#0's runqueue and ran resched_task() +for CPU#0. But it decided to not send an IPI that no CPU - due to +TS_POLLING. But CPU#0 never woke up after its NEED_RESCHED bit was set, +and only rescheduled to PID:5856 upon the next lapic timer IRQ. The +result was a 600+ usecs latency and a missed wakeup! + +the bug turned out to be an idle-wakeup bug introduced into the mainline +kernel this summer via an optimization in the x86_64 tree: + + commit 495ab9c045e1b0e5c82951b762257fe1c9d81564 + Author: Andi Kleen + Date: Mon Jun 26 13:59:11 2006 +0200 + + [PATCH] i386/x86-64/ia64: Move polling flag into thread_info_status + + During some profiling I noticed that default_idle causes a lot of + memory traffic. I think that is caused by the atomic operations + to clear/set the polling flag in thread_info. There is actually + no reason to make this atomic - only the idle thread does it + to itself, other CPUs only read it. So I moved it into ti->status. + +the problem is this type of change: + + if (!hlt_counter && boot_cpu_data.hlt_works_ok) { +- clear_thread_flag(TIF_POLLING_NRFLAG); ++ current_thread_info()->status &= ~TS_POLLING; + smp_mb__after_clear_bit(); + while (!need_resched()) { + local_irq_disable(); + +this changes clear_thread_flag() to an explicit clearing of TS_POLLING. +clear_thread_flag() is defined as: + + clear_bit(flag, &ti->flags); + +and clear_bit() is a LOCK-ed atomic instruction on all x86 platforms: + + static inline void clear_bit(int nr, volatile unsigned long * addr) + { + __asm__ __volatile__( LOCK_PREFIX + "btrl %1,%0" + +hence smp_mb__after_clear_bit() is defined as a simple compile barrier: + + #define smp_mb__after_clear_bit() barrier() + +but the explicit TS_POLLING clearing introduced by the patch: + ++ current_thread_info()->status &= ~TS_POLLING; + +is not an atomic op! So the clearing of the TS_POLLING bit is freely +reorderable with the reading of the NEED_RESCHED bit - and both now +reside in different memory addresses. + +CPU idle wakeup very much depends on ordered memory ops, the clearing of +the TS_POLLING flag must always be done before we test need_resched() +and hit the idle instruction(s). [Symmetrically, the wakeup code needs +to set NEED_RESCHED before it tests the TS_POLLING flag, so memory +ordering is paramount.] + +Fernando's dual-core Athlon64 system has a sufficiently advanced memory +ordering model so that it triggered this scenario very often. + +( And it also turned out that the reason why these latencies never + triggered on my testsystems is that i routinely use idle=poll, which + was the only idle variant not affected by this bug. ) + +The fix is to change the smp_mb__after_clear_bit() to an smp_mb(), to +act as an absolute barrier between the TS_POLLING write and the +NEED_RESCHED read. This affects almost all idling methods (default, +ACPI, APM), on all 3 x86 architectures: i386, x86_64, ia64. + +Signed-off-by: Ingo Molnar +Tested-by: Fernando Lopez-Lezcano +[chrisw: backport to 2.6.19.1] +Signed-off-by: Chris Wright +--- + arch/i386/kernel/apm.c | 6 +++++- + arch/i386/kernel/process.c | 7 ++++++- + arch/ia64/kernel/process.c | 10 ++++++++-- + arch/x86_64/kernel/process.c | 6 +++++- + drivers/acpi/processor_idle.c | 12 ++++++++++-- + 5 files changed, 34 insertions(+), 7 deletions(-) + +--- linux-2.6.19.1.orig/arch/i386/kernel/apm.c ++++ linux-2.6.19.1/arch/i386/kernel/apm.c +@@ -784,7 +784,11 @@ static int apm_do_idle(void) + polling = !!(current_thread_info()->status & TS_POLLING); + if (polling) { + current_thread_info()->status &= ~TS_POLLING; +- smp_mb__after_clear_bit(); ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); + } + if (!need_resched()) { + idled = 1; +--- linux-2.6.19.1.orig/arch/i386/kernel/process.c ++++ linux-2.6.19.1/arch/i386/kernel/process.c +@@ -103,7 +103,12 @@ void default_idle(void) + + if (!hlt_counter && boot_cpu_data.hlt_works_ok) { + current_thread_info()->status &= ~TS_POLLING; +- smp_mb__after_clear_bit(); ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); ++ + while (!need_resched()) { + local_irq_disable(); + if (!need_resched()) +--- linux-2.6.19.1.orig/arch/ia64/kernel/process.c ++++ linux-2.6.19.1/arch/ia64/kernel/process.c +@@ -268,10 +268,16 @@ cpu_idle (void) + + /* endless idle loop with no priority at all */ + while (1) { +- if (can_do_pal_halt) ++ if (can_do_pal_halt) { + current_thread_info()->status &= ~TS_POLLING; +- else ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); ++ } else { + current_thread_info()->status |= TS_POLLING; ++ } + + if (!need_resched()) { + void (*idle)(void); +--- linux-2.6.19.1.orig/arch/x86_64/kernel/process.c ++++ linux-2.6.19.1/arch/x86_64/kernel/process.c +@@ -111,7 +111,11 @@ static void default_idle(void) + local_irq_enable(); + + current_thread_info()->status &= ~TS_POLLING; +- smp_mb__after_clear_bit(); ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); + while (!need_resched()) { + local_irq_disable(); + if (!need_resched()) +--- linux-2.6.19.1.orig/drivers/acpi/processor_idle.c ++++ linux-2.6.19.1/drivers/acpi/processor_idle.c +@@ -211,7 +211,11 @@ acpi_processor_power_activate(struct acp + static void acpi_safe_halt(void) + { + current_thread_info()->status &= ~TS_POLLING; +- smp_mb__after_clear_bit(); ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); + if (!need_resched()) + safe_halt(); + current_thread_info()->status |= TS_POLLING; +@@ -345,7 +349,11 @@ static void acpi_processor_idle(void) + */ + if (cx->type == ACPI_STATE_C2 || cx->type == ACPI_STATE_C3) { + current_thread_info()->status &= ~TS_POLLING; +- smp_mb__after_clear_bit(); ++ /* ++ * TS_POLLING-cleared state must be visible before we ++ * test NEED_RESCHED: ++ */ ++ smp_mb(); + if (need_resched()) { + current_thread_info()->status |= TS_POLLING; + local_irq_enable(); diff --git a/releases/2.6.19.2/sched-remove-__cpuinitdata-anotation-to-cpu_isolated_map.patch b/releases/2.6.19.2/sched-remove-__cpuinitdata-anotation-to-cpu_isolated_map.patch new file mode 100644 index 00000000000..b10f7222364 --- /dev/null +++ b/releases/2.6.19.2/sched-remove-__cpuinitdata-anotation-to-cpu_isolated_map.patch @@ -0,0 +1,31 @@ +From linux-kernel-owner+chrisw=40sous-sol.org-S1751722AbWLMXRl@vger.kernel.org Wed Dec 13 15:23:21 2006 +Date: Wed, 13 Dec 2006 14:17:58 -0800 +From: Tim Chen +To: linux-kernel@vger.kernel.org +Cc: suresh.b.siddha@intel.com +Subject: sched: remove __cpuinitdata anotation to cpu_isolated_map + +The structure cpu_isolated_map is used not only during initialization. +Multi-core scheduler configuration changes and exclusive cpusets +use this during run time. During setting of sched_mc_power_savings + policy, this structure is accessed to update sched_domains. + +Signed-off-by: Tim Chen +Acked-by: Suresh Siddha +Acked-by: Ingo Molnar +Signed-off-by: Chris Wright +--- + kernel/sched.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/kernel/sched.c ++++ linux-2.6.19.1/kernel/sched.c +@@ -5493,7 +5493,7 @@ static void cpu_attach_domain(struct sch + } + + /* cpus with isolated domains */ +-static cpumask_t __cpuinitdata cpu_isolated_map = CPU_MASK_NONE; ++static cpumask_t cpu_isolated_map = CPU_MASK_NONE; + + /* Setup the mask of cpus configured for isolated domains */ + static int __init isolated_cpu_setup(char *str) diff --git a/releases/2.6.19.2/scsi-add-missing-cdb-clearing-in-scsi_execute.patch b/releases/2.6.19.2/scsi-add-missing-cdb-clearing-in-scsi_execute.patch new file mode 100644 index 00000000000..a6d083ddf44 --- /dev/null +++ b/releases/2.6.19.2/scsi-add-missing-cdb-clearing-in-scsi_execute.patch @@ -0,0 +1,33 @@ +From stable-bounces@linux.kernel.org Sat Dec 16 03:08:38 2006 +Date: Sat, 16 Dec 2006 20:02:32 +0900 +From: Tejun Heo +To: jens.axboe@oracle.com, dougg@torque.net, linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org, stable@kernel.org +Message-ID: <20061216110232.GF5400@htj.dyndns.org> +Subject: SCSI: add missing cdb clearing in scsi_execute() + +Clear-garbage-after-CDB patch missed scsi_execute() and it causes some +ODDs (HL-DT-ST DVD-RAM GSA-H30N) choke during SCSI scan. Note that +this patch is only for -stable. There is another more reliable fix +for this problem proposed for devel tree. + +http://thread.gmane.org/gmane.linux.ide/14605/focus=14605 + +Signed-off-by: Tejun Heo +Cc: Jens Axboe +Cc: Douglas Gilbert +Signed-off-by: Chris Wright + +--- + drivers/scsi/scsi_lib.c | 1 + + 1 file changed, 1 insertion(+) + +--- linux-2.6.19.1.orig/drivers/scsi/scsi_lib.c ++++ linux-2.6.19.1/drivers/scsi/scsi_lib.c +@@ -191,6 +191,7 @@ int scsi_execute(struct scsi_device *sde + goto out; + + req->cmd_len = COMMAND_SIZE(cmd[0]); ++ memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */ + memcpy(req->cmd, cmd, req->cmd_len); + req->sense = sense; + req->sense_len = 0; diff --git a/releases/2.6.19.2/series b/releases/2.6.19.2/series new file mode 100644 index 00000000000..b87a649f33f --- /dev/null +++ b/releases/2.6.19.2/series @@ -0,0 +1,51 @@ +dm-crypt-select-crypto_cbc.patch +sha512-fix-sha384-block-size.patch +read_zero_pagealigned-locking-fix.patch +ieee80211softmac-fix-mutex_lock-at-exit-of-ieee80211_softmac_get_genie.patch +x86-64-mark-rdtsc-as-sync-only-for-netburst-not-for-core2.patch +bonding-incorrect-bonding-state-reported-via-ioctl.patch +dvb-lgdt330x-fix-signal-lock-status-detection-bug.patch +v4l-fix-broken-tuner_lg_ntsc_tape-radio-support.patch +revert-zd1211rw-removed-unneeded-packed-attributes.patch +libata-handle-0xff-status-properly.patch +ieee1394-ohci1394-add-ppc_pmac-platform-code-to-driver-probe.patch +kbuild-don-t-put-temp-files-in-source.patch +arm-add-sys_-at-syscalls.patch +sched-remove-__cpuinitdata-anotation-to-cpu_isolated_map.patch +ib-srp-fix-fmr-mapping-for-32-bit-kernels-and-addresses-above-4g.patch +scsi-add-missing-cdb-clearing-in-scsi_execute.patch +bluetooth-add-packet-size-checks-for-capi-messages.patch +i2c-fix-broken-ds1337-initialization.patch +sched-fix-bad-missed-wakeups-in-the-i386-x86_64-ia64-acpi-and-apm-idle-code.patch +fix-for-shmem_truncate_range-bug_on.patch +smc911x-fix-netpoll-compilation-faliure.patch +fix-aoe-without-scatter-gather.patch +fix-reversed-logic-in-udp_get_port.patch +cciss-fix-xfer_read-xfer_write-in-do_cciss_request.patch +i386-cpu-hotplug-broken-with-2gb-vmsplit.patch +ramfs-breaks-without-config_block.patch +buglet-in-vmscan.c.patch +softmac-fixed-handling-of-deassociation-from-ap.patch +zd1211rw-call-ieee80211_rx-in-tasklet.patch +handle-ext3-directory-corruption-better.patch +corrupted-cramfs-filesystems-cause-kernel-oops.patch +ext2-skip-pages-past-number-of-blocks-in-ext2_find_entry.patch +pktgen-fix-module-load-unload-races.patch +sparc64-fix-mem-xxx-handling.patch +sparc64-handle-isa-devices-with-no-regs-property.patch +net-don-t-export-linux-random.h-outside-__kernel__.patch +sparc32-add-offset-in-pci_map_sg.patch +vm-fix-nasty-and-subtle-race-in-shared-mmap-ed-page-writeback.patch +v4l-cx2341x-audio_properties-is-an-u16-not-u8.patch +dvb-core-fix-bug-in-crc-32-checking-on-64-bit-systems.patch +v4l-cx88-fix-leadtek_eeprom-tagging.patch +ebtables-don-t-compute-gap-before-checking-struct-type.patch +sound-sparc-cs4231-fix-irq-return-value-and-initialization.patch +sound-sparc-cs4231-use-64-for-period_bytes_min.patch +ipv4-ipv6-fix-inet-6-device-initialization-order.patch +asix-fix-typo-for-ax88772-phy-selection.patch +netlabel-correctly-fill-in-unused-cipsov4-level-and-category-mappings.patch +connector-some-fixes-for-ia64-unaligned-access-errors.patch +fix-oom-killing-of-swapoff.patch +fix-incorrect-user-space-access-locking-in-mincore.patch +fix-up-page_mkclean_one-virtual-caches-s390.patch diff --git a/releases/2.6.19.2/sha512-fix-sha384-block-size.patch b/releases/2.6.19.2/sha512-fix-sha384-block-size.patch new file mode 100644 index 00000000000..947c6f52d3c --- /dev/null +++ b/releases/2.6.19.2/sha512-fix-sha384-block-size.patch @@ -0,0 +1,30 @@ +From stable-bounces@linux.kernel.org Sat Dec 9 16:37:52 2006 +Date: Sun, 10 Dec 2006 11:32:06 +1100 +Message-ID: <20061210003206.GA14068@gondor.apana.org.au> +From: Herbert Xu +To: stable@kernel.org +Subject: sha512: Fix sha384 block size + +The SHA384 block size should be 128 bytes, not 96 bytes. This was +spotted by Andrew Donofrio. + +This breaks HMAC which uses the block size during setup and the final +calculation. + +Signed-off-by: Herbert Xu +Signed-off-by: Chris Wright +--- + crypto/sha512.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/crypto/sha512.c ++++ linux-2.6.19.1/crypto/sha512.c +@@ -24,7 +24,7 @@ + + #define SHA384_DIGEST_SIZE 48 + #define SHA512_DIGEST_SIZE 64 +-#define SHA384_HMAC_BLOCK_SIZE 96 ++#define SHA384_HMAC_BLOCK_SIZE 128 + #define SHA512_HMAC_BLOCK_SIZE 128 + + struct sha512_ctx { diff --git a/releases/2.6.19.2/smc911x-fix-netpoll-compilation-faliure.patch b/releases/2.6.19.2/smc911x-fix-netpoll-compilation-faliure.patch new file mode 100644 index 00000000000..38beab86507 --- /dev/null +++ b/releases/2.6.19.2/smc911x-fix-netpoll-compilation-faliure.patch @@ -0,0 +1,33 @@ +From stable-bounces@linux.kernel.org Fri Dec 22 01:15:30 2006 +Message-Id: <200612220908.kBM98PCx018719@shell0.pdx.osdl.net> +To: torvalds@osdl.org +From: akpm@osdl.org +Date: Fri, 22 Dec 2006 01:08:24 -0800 +Cc: akpm@osdl.org, stable@kernel.org, jeff@garzik.org, vitalywool@gmail.com +Subject: smc911x: fix netpoll compilation faliure + +From: Vitaly Wool + +Fix the compilation failure for smc911x.c when NET_POLL_CONTROLLER is set. + +Signed-off-by: Vitaly Wool +Cc: Jeff Garzik +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Chris Wright +--- + + drivers/net/smc911x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/net/smc911x.c ++++ linux-2.6.19.1/drivers/net/smc911x.c +@@ -1331,7 +1331,7 @@ smc911x_rx_dma_irq(int dma, void *data) + static void smc911x_poll_controller(struct net_device *dev) + { + disable_irq(dev->irq); +- smc911x_interrupt(dev->irq, dev, NULL); ++ smc911x_interrupt(dev->irq, dev); + enable_irq(dev->irq); + } + #endif diff --git a/releases/2.6.19.2/softmac-fixed-handling-of-deassociation-from-ap.patch b/releases/2.6.19.2/softmac-fixed-handling-of-deassociation-from-ap.patch new file mode 100644 index 00000000000..410f4da67b9 --- /dev/null +++ b/releases/2.6.19.2/softmac-fixed-handling-of-deassociation-from-ap.patch @@ -0,0 +1,80 @@ +From stable-bounces@linux.kernel.org Sat Dec 30 13:24:14 2006 +Message-ID: <4596D796.6030202@gentoo.org> +Date: Sat, 30 Dec 2006 16:18:14 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: Ulrich Kunitz +Subject: softmac: Fixed handling of deassociation from AP + +From: Ulrich Kunitz + +In 2.6.19 a deauthentication from the AP doesn't start a +reassociation by the softmac code. It appears that +mac->associnfo.associating must be set and the +ieee80211softmac_assoc_work function must be scheduled. This patch +fixes that. + +Signed-off-by: Ulrich Kunitz +Signed-off-by: John W. Linville +Signed-off-by: Chris Wright +--- +Date: Sun, 3 Dec 2006 15:32:00 +0000 (+0100) +Subject: [PATCH] softmac: Fixed handling of deassociation from AP +X-Git-Tag: v2.6.20-rc1 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=2b50c24554d31c2db2f93b1151b5991e62f96594 + + net/ieee80211/softmac/ieee80211softmac_assoc.c | 14 ++++++++++++-- + net/ieee80211/softmac/ieee80211softmac_auth.c | 2 ++ + net/ieee80211/softmac/ieee80211softmac_priv.h | 2 ++ + 3 files changed, 16 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/net/ieee80211/softmac/ieee80211softmac_assoc.c ++++ linux-2.6.19.1/net/ieee80211/softmac/ieee80211softmac_assoc.c +@@ -427,6 +427,17 @@ ieee80211softmac_handle_assoc_response(s + return 0; + } + ++void ++ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac) ++{ ++ unsigned long flags; ++ ++ spin_lock_irqsave(&mac->lock, flags); ++ mac->associnfo.associating = 1; ++ schedule_work(&mac->associnfo.work); ++ spin_unlock_irqrestore(&mac->lock, flags); ++} ++ + int + ieee80211softmac_handle_disassoc(struct net_device * dev, + struct ieee80211_disassoc *disassoc) +@@ -445,8 +456,7 @@ ieee80211softmac_handle_disassoc(struct + dprintk(KERN_INFO PFX "got disassoc frame\n"); + ieee80211softmac_disassoc(mac); + +- /* try to reassociate */ +- schedule_work(&mac->associnfo.work); ++ ieee80211softmac_try_reassoc(mac); + + return 0; + } +--- linux-2.6.19.1.orig/net/ieee80211/softmac/ieee80211softmac_auth.c ++++ linux-2.6.19.1/net/ieee80211/softmac/ieee80211softmac_auth.c +@@ -328,6 +328,8 @@ ieee80211softmac_deauth_from_net(struct + /* can't transmit data right now... */ + netif_carrier_off(mac->dev); + spin_unlock_irqrestore(&mac->lock, flags); ++ ++ ieee80211softmac_try_reassoc(mac); + } + + /* +--- linux-2.6.19.1.orig/net/ieee80211/softmac/ieee80211softmac_priv.h ++++ linux-2.6.19.1/net/ieee80211/softmac/ieee80211softmac_priv.h +@@ -238,4 +238,6 @@ void ieee80211softmac_call_events_locked + int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, + int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask); + ++void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac); ++ + #endif /* IEEE80211SOFTMAC_PRIV_H_ */ diff --git a/releases/2.6.19.2/sound-sparc-cs4231-fix-irq-return-value-and-initialization.patch b/releases/2.6.19.2/sound-sparc-cs4231-fix-irq-return-value-and-initialization.patch new file mode 100644 index 00000000000..c551400f57b --- /dev/null +++ b/releases/2.6.19.2/sound-sparc-cs4231-fix-irq-return-value-and-initialization.patch @@ -0,0 +1,89 @@ +From stable-bounces@linux.kernel.org Thu Jan 4 17:10:49 2007 +Date: Thu, 04 Jan 2007 17:03:38 -0800 (PST) +Message-Id: <20070104.170338.48396666.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: SOUND: Sparc CS4231: Fix IRQ return value and initialization. + +From: Georg Chini + +SBUS: Change IRQ-handler return value from 0 to IRQ_HANDLED and +fix some initialisation problems. + +Change period_bytes_min from 4096 to 256 to allow driver to work with +low latency (VOIP) applications. Hope this does not break EBUS. + +Signed-off-by: Georg Chini +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- +commit d35a1b9e10481c9f1d3b87e778a0f1f6a0a2dd48 + + sound/sparc/cs4231.c | 26 ++++++++++++-------------- + 1 file changed, 12 insertions(+), 14 deletions(-) + +--- linux-2.6.19.1.orig/sound/sparc/cs4231.c ++++ linux-2.6.19.1/sound/sparc/cs4231.c +@@ -1268,7 +1268,7 @@ static struct snd_pcm_hardware snd_cs423 + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), +- .period_bytes_min = 4096, ++ .period_bytes_min = 256, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, +@@ -1288,7 +1288,7 @@ static struct snd_pcm_hardware snd_cs423 + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), +- .period_bytes_min = 4096, ++ .period_bytes_min = 256, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, +@@ -1796,7 +1796,7 @@ static irqreturn_t snd_cs4231_sbus_inter + snd_cs4231_outm(chip, CS4231_IRQ_STATUS, ~CS4231_ALL_IRQS | ~status, 0); + spin_unlock_irqrestore(&chip->lock, flags); + +- return 0; ++ return IRQ_HANDLED; + } + + /* +@@ -1821,7 +1821,6 @@ static int sbus_dma_request(struct cs423 + if (!(csr & test)) + goto out; + err = -EBUSY; +- csr = sbus_readl(base->regs + APCCSR); + test = APC_XINT_CNVA; + if ( base->dir == APC_PLAY ) + test = APC_XINT_PNVA; +@@ -1862,17 +1861,16 @@ static void sbus_dma_enable(struct cs423 + + spin_lock_irqsave(&base->lock, flags); + if (!on) { +- if (base->dir == APC_PLAY) { +- sbus_writel(0, base->regs + base->dir + APCNVA); +- sbus_writel(1, base->regs + base->dir + APCC); +- } +- else +- { +- sbus_writel(0, base->regs + base->dir + APCNC); +- sbus_writel(0, base->regs + base->dir + APCVA); +- } ++ sbus_writel(0, base->regs + base->dir + APCNC); ++ sbus_writel(0, base->regs + base->dir + APCNVA); ++ sbus_writel(0, base->regs + base->dir + APCC); ++ sbus_writel(0, base->regs + base->dir + APCVA); ++ ++ /* ACK any APC interrupts. */ ++ csr = sbus_readl(base->regs + APCCSR); ++ sbus_writel(csr, base->regs + APCCSR); + } +- udelay(600); ++ udelay(1000); + csr = sbus_readl(base->regs + APCCSR); + shift = 0; + if ( base->dir == APC_PLAY ) diff --git a/releases/2.6.19.2/sound-sparc-cs4231-use-64-for-period_bytes_min.patch b/releases/2.6.19.2/sound-sparc-cs4231-use-64-for-period_bytes_min.patch new file mode 100644 index 00000000000..ca0932e55d1 --- /dev/null +++ b/releases/2.6.19.2/sound-sparc-cs4231-use-64-for-period_bytes_min.patch @@ -0,0 +1,40 @@ +From stable-bounces@linux.kernel.org Thu Jan 4 17:11:45 2007 +Date: Thu, 04 Jan 2007 17:04:31 -0800 (PST) +Message-Id: <20070104.170431.123973077.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Cc: bunk@stusta.de +Subject: SOUND: Sparc CS4231: Use 64 for period_bytes_min + +This matches what the ISA cs4231 driver uses. + +Tested by Georg Chini. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright +--- +commit f9af1d9deaaffe6803dec693748498886915d766 + + sound/sparc/cs4231.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- linux-2.6.19.1.orig/sound/sparc/cs4231.c ++++ linux-2.6.19.1/sound/sparc/cs4231.c +@@ -1268,7 +1268,7 @@ static struct snd_pcm_hardware snd_cs423 + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), +- .period_bytes_min = 256, ++ .period_bytes_min = 64, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, +@@ -1288,7 +1288,7 @@ static struct snd_pcm_hardware snd_cs423 + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = (32*1024), +- .period_bytes_min = 256, ++ .period_bytes_min = 64, + .period_bytes_max = (32*1024), + .periods_min = 1, + .periods_max = 1024, diff --git a/releases/2.6.19.2/sparc32-add-offset-in-pci_map_sg.patch b/releases/2.6.19.2/sparc32-add-offset-in-pci_map_sg.patch new file mode 100644 index 00000000000..cd0b771aeaf --- /dev/null +++ b/releases/2.6.19.2/sparc32-add-offset-in-pci_map_sg.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Tue Jan 2 00:16:30 2007 +Date: Tue, 02 Jan 2007 00:09:25 -0800 (PST) +Message-Id: <20070102.000925.85688510.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: sparc32: add offset in pci_map_sg() + +From: Jan Andersson + +Add sg->offset to sg->dvma_address in pci_map_sg() on sparc32. Without the +offset, transfers to buffers that do not begin on a page boundary will not +work as expected. + +Signed-off-by: Jan Andersson +Cc: "David S. Miller" +Cc: William Lee Irwin III +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Chris Wright + +--- + arch/sparc/kernel/ioport.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/arch/sparc/kernel/ioport.c ++++ linux-2.6.19.1/arch/sparc/kernel/ioport.c +@@ -728,7 +728,8 @@ int pci_map_sg(struct pci_dev *hwdev, st + /* IIep is write-through, not flushing. */ + for (n = 0; n < nents; n++) { + BUG_ON(page_address(sg->page) == NULL); +- sg->dvma_address = virt_to_phys(page_address(sg->page)); ++ sg->dvma_address = ++ virt_to_phys(page_address(sg->page)) + sg->offset; + sg->dvma_length = sg->length; + sg++; + } diff --git a/releases/2.6.19.2/sparc64-fix-mem-xxx-handling.patch b/releases/2.6.19.2/sparc64-fix-mem-xxx-handling.patch new file mode 100644 index 00000000000..6b6104f2597 --- /dev/null +++ b/releases/2.6.19.2/sparc64-fix-mem-xxx-handling.patch @@ -0,0 +1,190 @@ +From stable-bounces@linux.kernel.org Tue Jan 2 00:10:39 2007 +Date: Tue, 02 Jan 2007 00:03:37 -0800 (PST) +Message-Id: <20070102.000337.95059128.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: SPARC64: Fix "mem=xxx" handling. + +We were not being careful enough. When we trim the physical +memory areas, we have to make sure we don't remove the kernel +image or initial ramdisk image ranges. + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- + arch/sparc64/mm/init.c | 147 +++++++++++++++++++++++++++++++++++++++++-------- + 1 file changed, 124 insertions(+), 23 deletions(-) + +--- linux-2.6.19.1.orig/arch/sparc64/mm/init.c ++++ linux-2.6.19.1/arch/sparc64/mm/init.c +@@ -872,6 +872,115 @@ static unsigned long __init choose_bootm + prom_halt(); + } + ++static void __init trim_pavail(unsigned long *cur_size_p, ++ unsigned long *end_of_phys_p) ++{ ++ unsigned long to_trim = *cur_size_p - cmdline_memory_size; ++ unsigned long avoid_start, avoid_end; ++ int i; ++ ++ to_trim = PAGE_ALIGN(to_trim); ++ ++ avoid_start = avoid_end = 0; ++#ifdef CONFIG_BLK_DEV_INITRD ++ avoid_start = initrd_start; ++ avoid_end = PAGE_ALIGN(initrd_end); ++#endif ++ ++ /* Trim some pavail[] entries in order to satisfy the ++ * requested "mem=xxx" kernel command line specification. ++ * ++ * We must not trim off the kernel image area nor the ++ * initial ramdisk range (if any). Also, we must not trim ++ * any pavail[] entry down to zero in order to preserve ++ * the invariant that all pavail[] entries have a non-zero ++ * size which is assumed by all of the code in here. ++ */ ++ for (i = 0; i < pavail_ents; i++) { ++ unsigned long start, end, kern_end; ++ unsigned long trim_low, trim_high, n; ++ ++ kern_end = PAGE_ALIGN(kern_base + kern_size); ++ ++ trim_low = start = pavail[i].phys_addr; ++ trim_high = end = start + pavail[i].reg_size; ++ ++ if (kern_base >= start && ++ kern_base < end) { ++ trim_low = kern_base; ++ if (kern_end >= end) ++ continue; ++ } ++ if (kern_end >= start && ++ kern_end < end) { ++ trim_high = kern_end; ++ } ++ if (avoid_start && ++ avoid_start >= start && ++ avoid_start < end) { ++ if (trim_low > avoid_start) ++ trim_low = avoid_start; ++ if (avoid_end >= end) ++ continue; ++ } ++ if (avoid_end && ++ avoid_end >= start && ++ avoid_end < end) { ++ if (trim_high < avoid_end) ++ trim_high = avoid_end; ++ } ++ ++ if (trim_high <= trim_low) ++ continue; ++ ++ if (trim_low == start && trim_high == end) { ++ /* Whole chunk is available for trimming. ++ * Trim all except one page, in order to keep ++ * entry non-empty. ++ */ ++ n = (end - start) - PAGE_SIZE; ++ if (n > to_trim) ++ n = to_trim; ++ ++ if (n) { ++ pavail[i].phys_addr += n; ++ pavail[i].reg_size -= n; ++ to_trim -= n; ++ } ++ } else { ++ n = (trim_low - start); ++ if (n > to_trim) ++ n = to_trim; ++ ++ if (n) { ++ pavail[i].phys_addr += n; ++ pavail[i].reg_size -= n; ++ to_trim -= n; ++ } ++ if (to_trim) { ++ n = end - trim_high; ++ if (n > to_trim) ++ n = to_trim; ++ if (n) { ++ pavail[i].reg_size -= n; ++ to_trim -= n; ++ } ++ } ++ } ++ ++ if (!to_trim) ++ break; ++ } ++ ++ /* Recalculate. */ ++ *cur_size_p = 0UL; ++ for (i = 0; i < pavail_ents; i++) { ++ *end_of_phys_p = pavail[i].phys_addr + ++ pavail[i].reg_size; ++ *cur_size_p += pavail[i].reg_size; ++ } ++} ++ + static unsigned long __init bootmem_init(unsigned long *pages_avail, + unsigned long phys_base) + { +@@ -889,31 +998,13 @@ static unsigned long __init bootmem_init + end_of_phys_memory = pavail[i].phys_addr + + pavail[i].reg_size; + bytes_avail += pavail[i].reg_size; +- if (cmdline_memory_size) { +- if (bytes_avail > cmdline_memory_size) { +- unsigned long slack = bytes_avail - cmdline_memory_size; +- +- bytes_avail -= slack; +- end_of_phys_memory -= slack; +- +- pavail[i].reg_size -= slack; +- if ((long)pavail[i].reg_size <= 0L) { +- pavail[i].phys_addr = 0xdeadbeefUL; +- pavail[i].reg_size = 0UL; +- pavail_ents = i; +- } else { +- pavail[i+1].reg_size = 0Ul; +- pavail[i+1].phys_addr = 0xdeadbeefUL; +- pavail_ents = i + 1; +- } +- break; +- } +- } + } + +- *pages_avail = bytes_avail >> PAGE_SHIFT; +- +- end_pfn = end_of_phys_memory >> PAGE_SHIFT; ++ /* Determine the location of the initial ramdisk before trying ++ * to honor the "mem=xxx" command line argument. We must know ++ * where the kernel image and the ramdisk image are so that we ++ * do not trim those two areas from the physical memory map. ++ */ + + #ifdef CONFIG_BLK_DEV_INITRD + /* Now have to check initial ramdisk, so that bootmap does not overwrite it */ +@@ -932,6 +1023,16 @@ static unsigned long __init bootmem_init + } + } + #endif ++ ++ if (cmdline_memory_size && ++ bytes_avail > cmdline_memory_size) ++ trim_pavail(&bytes_avail, ++ &end_of_phys_memory); ++ ++ *pages_avail = bytes_avail >> PAGE_SHIFT; ++ ++ end_pfn = end_of_phys_memory >> PAGE_SHIFT; ++ + /* Initialize the boot-time allocator. */ + max_pfn = max_low_pfn = end_pfn; + min_low_pfn = (phys_base >> PAGE_SHIFT); diff --git a/releases/2.6.19.2/sparc64-handle-isa-devices-with-no-regs-property.patch b/releases/2.6.19.2/sparc64-handle-isa-devices-with-no-regs-property.patch new file mode 100644 index 00000000000..f13e546711b --- /dev/null +++ b/releases/2.6.19.2/sparc64-handle-isa-devices-with-no-regs-property.patch @@ -0,0 +1,92 @@ +From stable-bounces@linux.kernel.org Tue Jan 2 00:13:01 2007 +Date: Tue, 02 Jan 2007 00:06:00 -0800 (PST) +Message-Id: <20070102.000600.59655621.davem@davemloft.net> +To: stable@kernel.org +From: David Miller +Subject: SPARC64: Handle ISA devices with no 'regs' property. + +And this points out that the return value from +isa_dev_get_resource() and the 'pregs' arg to +isa_dev_get_irq() are totally unused. + +Based upon a patch from Richard Mortimer + +Signed-off-by: David S. Miller +Signed-off-by: Chris Wright + +--- + arch/sparc64/kernel/isa.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +--- linux-2.6.19.1.orig/arch/sparc64/kernel/isa.c ++++ linux-2.6.19.1/arch/sparc64/kernel/isa.c +@@ -22,14 +22,15 @@ static void __init report_dev(struct spa + printk(" [%s", isa_dev->prom_node->name); + } + +-static struct linux_prom_registers * __init +-isa_dev_get_resource(struct sparc_isa_device *isa_dev) ++static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev) + { + struct linux_prom_registers *pregs; + unsigned long base, len; + int prop_len; + + pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len); ++ if (!pregs) ++ return; + + /* Only the first one is interesting. */ + len = pregs[0].reg_size; +@@ -44,12 +45,9 @@ isa_dev_get_resource(struct sparc_isa_de + + request_resource(&isa_dev->bus->parent->io_space, + &isa_dev->resource); +- +- return pregs; + } + +-static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev, +- struct linux_prom_registers *pregs) ++static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev) + { + struct of_device *op = of_find_device_by_node(isa_dev->prom_node); + +@@ -69,7 +67,6 @@ static void __init isa_fill_children(str + + printk(" ->"); + while (dp) { +- struct linux_prom_registers *regs; + struct sparc_isa_device *isa_dev; + + isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); +@@ -87,8 +84,8 @@ static void __init isa_fill_children(str + isa_dev->bus = parent_isa_dev->bus; + isa_dev->prom_node = dp; + +- regs = isa_dev_get_resource(isa_dev); +- isa_dev_get_irq(isa_dev, regs); ++ isa_dev_get_resource(isa_dev); ++ isa_dev_get_irq(isa_dev); + + report_dev(isa_dev, 1); + +@@ -101,7 +98,6 @@ static void __init isa_fill_devices(stru + struct device_node *dp = isa_br->prom_node->child; + + while (dp) { +- struct linux_prom_registers *regs; + struct sparc_isa_device *isa_dev; + + isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); +@@ -141,8 +137,8 @@ static void __init isa_fill_devices(stru + isa_dev->bus = isa_br; + isa_dev->prom_node = dp; + +- regs = isa_dev_get_resource(isa_dev); +- isa_dev_get_irq(isa_dev, regs); ++ isa_dev_get_resource(isa_dev); ++ isa_dev_get_irq(isa_dev); + + report_dev(isa_dev, 0); + diff --git a/releases/2.6.19.2/v4l-cx2341x-audio_properties-is-an-u16-not-u8.patch b/releases/2.6.19.2/v4l-cx2341x-audio_properties-is-an-u16-not-u8.patch new file mode 100644 index 00000000000..c3690560008 --- /dev/null +++ b/releases/2.6.19.2/v4l-cx2341x-audio_properties-is-an-u16-not-u8.patch @@ -0,0 +1,33 @@ +From stable-bounces@linux.kernel.org Wed Jan 3 20:28:09 2007 +Message-ID: <459C80A7.2010901@linuxtv.org> +Date: Wed, 03 Jan 2007 23:20:55 -0500 +From: Michael Krufky +To: stable@kernel.org +Cc: Hans Verkuil , v4l-dvb maintainer list +Subject: V4L: cx2341x: audio_properties is an u16, not u8 + +From: Hans Verkuil + +This bug broke the MPEG audio mode controls. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Chris Wright +--- +(cherry picked from commit cb2c7b4927c8f376b7ba9557978d8c59ed472664) + + include/media/cx2341x.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/include/media/cx2341x.h ++++ linux-2.6.19.1/include/media/cx2341x.h +@@ -49,7 +49,7 @@ struct cx2341x_mpeg_params { + enum v4l2_mpeg_audio_mode_extension audio_mode_extension; + enum v4l2_mpeg_audio_emphasis audio_emphasis; + enum v4l2_mpeg_audio_crc audio_crc; +- u8 audio_properties; ++ u16 audio_properties; + + /* video */ + enum v4l2_mpeg_video_encoding video_encoding; diff --git a/releases/2.6.19.2/v4l-cx88-fix-leadtek_eeprom-tagging.patch b/releases/2.6.19.2/v4l-cx88-fix-leadtek_eeprom-tagging.patch new file mode 100644 index 00000000000..39957d2233f --- /dev/null +++ b/releases/2.6.19.2/v4l-cx88-fix-leadtek_eeprom-tagging.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Wed Jan 3 20:28:25 2007 +Message-ID: <459C80AF.2070409@linuxtv.org> +Date: Wed, 03 Jan 2007 23:21:03 -0500 +From: Michael Krufky +To: stable@kernel.org +Cc: Jean Delvare , v4l-dvb maintainer list +Subject: V4L: cx88: Fix leadtek_eeprom tagging + +From: Jean Delvare + +reference to .init.text: from .text between 'cx88_card_setup' +(at offset 0x68c) and 'cx88_risc_field' +Caused by leadtek_eeprom() being declared __devinit and called from +a non-devinit context. + +Signed-off-by: Jean Delvare +Signed-off-by: Michael Krufky +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Chris Wright +--- +(cherry picked from commit 69f7e75a9d45e5eaca16917a8d0dedf76149f13f) + + drivers/media/video/cx88/cx88-cards.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/drivers/media/video/cx88/cx88-cards.c ++++ linux-2.6.19.1/drivers/media/video/cx88/cx88-cards.c +@@ -1610,7 +1610,7 @@ const unsigned int cx88_idcount = ARRAY_ + /* ----------------------------------------------------------------------- */ + /* some leadtek specific stuff */ + +-static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) ++static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data) + { + /* This is just for the "Winfast 2000XP Expert" board ATM; I don't have data on + * any others. diff --git a/releases/2.6.19.2/v4l-fix-broken-tuner_lg_ntsc_tape-radio-support.patch b/releases/2.6.19.2/v4l-fix-broken-tuner_lg_ntsc_tape-radio-support.patch new file mode 100644 index 00000000000..ce5ca3cc1ac --- /dev/null +++ b/releases/2.6.19.2/v4l-fix-broken-tuner_lg_ntsc_tape-radio-support.patch @@ -0,0 +1,78 @@ +From stable-bounces@linux.kernel.org Mon Dec 11 21:42:38 2006 +Message-ID: <457E3FE7.5090709@linuxtv.org> +Date: Tue, 12 Dec 2006 00:36:39 -0500 +From: Michael Krufky +To: stable@kernel.org +Cc: Hans Verkuil , v4l-dvb maintainer list , Mauro Carvalho Chehab +Subject: V4L: Fix broken TUNER_LG_NTSC_TAPE radio support + +From: Hans Verkuil + +The TUNER_LG_NTSC_TAPE is identical in all respects to the +TUNER_PHILIPS_FM1236_MK3. So use the params struct for the Philips tuner. +Also add this LG_NTSC_TAPE tuner to the switches where radio specific +parameters are set so it behaves like a TUNER_PHILIPS_FM1236_MK3. This +change fixes the radio support for this tuner (the wrong bandswitch byte +was used). + +Thanks to Andy Walls for finding this bug. + +Signed-off-by: Hans Verkuil +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Michael Krufky +Signed-off-by: Chris Wright + +--- + + drivers/media/video/tuner-simple.c | 2 ++ + drivers/media/video/tuner-types.c | 14 ++------------ + 2 files changed, 4 insertions(+), 12 deletions(-) + +--- linux-2.6.19.1.orig/drivers/media/video/tuner-simple.c ++++ linux-2.6.19.1/drivers/media/video/tuner-simple.c +@@ -108,6 +108,7 @@ static int tuner_stereo(struct i2c_clien + case TUNER_PHILIPS_FM1216ME_MK3: + case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FM1256_IH3: ++ case TUNER_LG_NTSC_TAPE: + stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3); + break; + default: +@@ -421,6 +422,7 @@ static void default_set_radio_freq(struc + case TUNER_PHILIPS_FM1216ME_MK3: + case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FMD1216ME_MK3: ++ case TUNER_LG_NTSC_TAPE: + buffer[3] = 0x19; + break; + case TUNER_TNF_5335MF: +--- linux-2.6.19.1.orig/drivers/media/video/tuner-types.c ++++ linux-2.6.19.1/drivers/media/video/tuner-types.c +@@ -672,16 +672,6 @@ static struct tuner_params tuner_panason + }, + }; + +-/* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */ +- +-static struct tuner_params tuner_lg_ntsc_tape_params[] = { +- { +- .type = TUNER_PARAM_TYPE_NTSC, +- .ranges = tuner_fm1236_mk3_ntsc_ranges, +- .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges), +- }, +-}; +- + /* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */ + + static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = { +@@ -1331,8 +1321,8 @@ struct tunertype tuners[] = { + }, + [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */ + .name = "LG NTSC (TAPE series)", +- .params = tuner_lg_ntsc_tape_params, +- .count = ARRAY_SIZE(tuner_lg_ntsc_tape_params), ++ .params = tuner_fm1236_mk3_params, ++ .count = ARRAY_SIZE(tuner_fm1236_mk3_params), + }, + [TUNER_TNF_8831BGFF] = { /* Philips PAL */ + .name = "Tenna TNF 8831 BGFF)", diff --git a/releases/2.6.19.2/vm-fix-nasty-and-subtle-race-in-shared-mmap-ed-page-writeback.patch b/releases/2.6.19.2/vm-fix-nasty-and-subtle-race-in-shared-mmap-ed-page-writeback.patch new file mode 100644 index 00000000000..173014e4e19 --- /dev/null +++ b/releases/2.6.19.2/vm-fix-nasty-and-subtle-race-in-shared-mmap-ed-page-writeback.patch @@ -0,0 +1,111 @@ +From 7658cc289288b8ae7dd2c2224549a048431222b3 Mon Sep 17 00:00:00 2001 +From: Linus Torvalds +Date: Fri, 29 Dec 2006 10:00:58 -0800 +Subject: VM: Fix nasty and subtle race in shared mmap'ed page writeback + +The VM layer (on the face of it, fairly reasonably) expected that when +it does a ->writepage() call to the filesystem, it would write out the +full page at that point in time. Especially since it had earlier marked +the whole page dirty with "set_page_dirty()". + +But that isn't actually the case: ->writepage() does not actually write +a page, it writes the parts of the page that have been explicitly marked +dirty before, *and* that had not got written out for other reasons since +the last time we told it they were dirty. + +That last caveat is the important one. + +Which _most_ of the time ends up being the whole page (since we had +called "set_page_dirty()" on the page earlier), but if the filesystem +had done any dirty flushing of its own (for example, to honor some +internal write ordering guarantees), it might end up doing only a +partial page IO (or none at all) when ->writepage() is actually called. + +That is the correct thing in general (since we actually often _want_ +only the known-dirty parts of the page to be written out), but the +shared dirty page handling had implicitly forgotten about these details, +and had a number of cases where it was doing just the "->writepage()" +part, without telling the low-level filesystem that the whole page might +have been re-dirtied as part of being mapped writably into user space. + +Since most of the time the FS did actually write out the full page, we +didn't notice this for a loong time, and this needed some really odd +patterns to trigger. But it caused occasional corruption with rtorrent +and with the Debian "apt" database, because both use shared mmaps to +update the end result. + +This fixes it. Finally. After way too much hair-pulling. + +Acked-by: Nick Piggin +Acked-by: Martin J. Bligh +Acked-by: Martin Michlmayr +Acked-by: Martin Johansson +Acked-by: Ingo Molnar +Acked-by: Andrei Popa +Cc: High Dickins +Cc: Andrew Morton , +Cc: Peter Zijlstra +Cc: Segher Boessenkool +Cc: David Miller +Cc: Arjan van de Ven +Cc: Gordon Farquharson +Cc: Guillaume Chazarain +Cc: Theodore Tso +Cc: Kenneth Cheng +Cc: Tobias Diedrich +Signed-off-by: Linus Torvalds +[chrisw: backport to 2.6.19.1] +Signed-off-by: Chris Wright +--- + mm/page-writeback.c | 39 ++++++++++++++++++++++++++++++++++----- + 1 file changed, 34 insertions(+), 5 deletions(-) + +--- linux-2.6.19.1.orig/mm/page-writeback.c ++++ linux-2.6.19.1/mm/page-writeback.c +@@ -893,12 +893,41 @@ int clear_page_dirty_for_io(struct page + { + struct address_space *mapping = page_mapping(page); + +- if (mapping) { ++ if (mapping && mapping_cap_account_dirty(mapping)) { ++ /* ++ * Yes, Virginia, this is indeed insane. ++ * ++ * We use this sequence to make sure that ++ * (a) we account for dirty stats properly ++ * (b) we tell the low-level filesystem to ++ * mark the whole page dirty if it was ++ * dirty in a pagetable. Only to then ++ * (c) clean the page again and return 1 to ++ * cause the writeback. ++ * ++ * This way we avoid all nasty races with the ++ * dirty bit in multiple places and clearing ++ * them concurrently from different threads. ++ * ++ * Note! Normally the "set_page_dirty(page)" ++ * has no effect on the actual dirty bit - since ++ * that will already usually be set. But we ++ * need the side effects, and it can help us ++ * avoid races. ++ * ++ * We basically use the page "master dirty bit" ++ * as a serialization point for all the different ++ * threads doing their things. ++ * ++ * FIXME! We still have a race here: if somebody ++ * adds the page back to the page tables in ++ * between the "page_mkclean()" and the "TestClearPageDirty()", ++ * we might have it mapped without the dirty bit set. ++ */ ++ if (page_mkclean(page)) ++ set_page_dirty(page); + if (TestClearPageDirty(page)) { +- if (mapping_cap_account_dirty(mapping)) { +- page_mkclean(page); +- dec_zone_page_state(page, NR_FILE_DIRTY); +- } ++ dec_zone_page_state(page, NR_FILE_DIRTY); + return 1; + } + return 0; diff --git a/releases/2.6.19.2/x86-64-mark-rdtsc-as-sync-only-for-netburst-not-for-core2.patch b/releases/2.6.19.2/x86-64-mark-rdtsc-as-sync-only-for-netburst-not-for-core2.patch new file mode 100644 index 00000000000..38f0e089abc --- /dev/null +++ b/releases/2.6.19.2/x86-64-mark-rdtsc-as-sync-only-for-netburst-not-for-core2.patch @@ -0,0 +1,43 @@ +From stable-bounces@linux.kernel.org Mon Dec 11 13:26:59 2006 +From: Arjan van de Ven +To: stable@kernel.org +Date: Mon, 11 Dec 2006 21:45:01 +0100 +Message-Id: <1165869901.27217.439.camel@laptopd505.fenrus.org> +Subject: x86-64: Mark rdtsc as sync only for netburst, not for core2 + +On the Core2 cpus, the rdtsc instruction is not serializing (as defined +in the architecture reference since rdtsc exists) and due to the deep +speculation of these cores, it's possible that you can observe time go +backwards between cores due to this speculation. Since the kernel +already deals with this with the SYNC_RDTSC flag, the solution is +simple, only assume that the instruction is serializing on family 15... + +The price one pays for this is a slightly slower gettimeofday (by a +dozen or two cycles), but that increase is quite small to pay for a +really-going-forward tsc counter. + +Signed-off-by: Arjan van de Ven +Signed-off-by: Andi Kleen +Signed-off-by: Chris Wright +--- +Commit: f3d73707a1e84f0687a05144b70b660441e999c7 +Author: Arjan van de Ven +AuthorDate: Thu Dec 7 02:14:12 2006 +0100 + + arch/x86_64/kernel/setup.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- linux-2.6.19.1.orig/arch/x86_64/kernel/setup.c ++++ linux-2.6.19.1/arch/x86_64/kernel/setup.c +@@ -854,7 +854,10 @@ static void __cpuinit init_intel(struct + set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); + if (c->x86 == 6) + set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); +- set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); ++ if (c->x86 == 15) ++ set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); ++ else ++ clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability); + c->x86_max_cores = intel_num_cpu_cores(c); + + srat_detect_node(); diff --git a/releases/2.6.19.2/zd1211rw-call-ieee80211_rx-in-tasklet.patch b/releases/2.6.19.2/zd1211rw-call-ieee80211_rx-in-tasklet.patch new file mode 100644 index 00000000000..cca2ab68a6b --- /dev/null +++ b/releases/2.6.19.2/zd1211rw-call-ieee80211_rx-in-tasklet.patch @@ -0,0 +1,223 @@ +From stable-bounces@linux.kernel.org Sat Dec 30 13:41:14 2006 +Message-ID: <4596DB95.8060004@gentoo.org> +Date: Sat, 30 Dec 2006 16:35:17 -0500 +From: Daniel Drake +To: stable@kernel.org +Cc: Ulrich Kunitz +Subject: zd1211rw: Call ieee80211_rx in tasklet + +From: Ulrich Kunitz + +[PATCH] zd1211rw: Call ieee80211_rx in tasklet + +The driver called ieee80211_rx in hardware interrupt context. This has +been against the intention of the ieee80211_rx function. It caused a bug +in the crypto routines used by WPA. This patch calls ieee80211_rx in a +tasklet. + +Signed-off-by: Ulrich Kunitz +Signed-off-by: Andrew Morton +Signed-off-by: John W. Linville +Signed-off-by: Chris Wright +--- +Date: Sun, 10 Dec 2006 19:13:12 +0000 (-0800) +Subject: [PATCH] zd1211rw: Call ieee80211_rx in tasklet +X-Git-Tag: v2.6.20-rc2 +X-Git-Url: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4d1feabcbf41f875447a392015acd0796f57baf6 + + drivers/net/wireless/zd1211rw/zd_mac.c | 91 ++++++++++++++++++++++++--------- + drivers/net/wireless/zd1211rw/zd_mac.h | 6 +- + drivers/net/wireless/zd1211rw/zd_usb.c | 4 - + 3 files changed, 75 insertions(+), 26 deletions(-) + +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.c ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.c +@@ -37,6 +37,8 @@ static void housekeeping_init(struct zd_ + static void housekeeping_enable(struct zd_mac *mac); + static void housekeeping_disable(struct zd_mac *mac); + ++static void do_rx(unsigned long mac_ptr); ++ + int zd_mac_init(struct zd_mac *mac, + struct net_device *netdev, + struct usb_interface *intf) +@@ -47,6 +49,10 @@ int zd_mac_init(struct zd_mac *mac, + spin_lock_init(&mac->lock); + mac->netdev = netdev; + ++ skb_queue_head_init(&mac->rx_queue); ++ tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); ++ tasklet_disable(&mac->rx_tasklet); ++ + ieee_init(ieee); + softmac_init(ieee80211_priv(netdev)); + zd_chip_init(&mac->chip, netdev, intf); +@@ -132,6 +138,8 @@ out: + + void zd_mac_clear(struct zd_mac *mac) + { ++ skb_queue_purge(&mac->rx_queue); ++ tasklet_kill(&mac->rx_tasklet); + zd_chip_clear(&mac->chip); + ZD_ASSERT(!spin_is_locked(&mac->lock)); + ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); +@@ -160,6 +168,8 @@ int zd_mac_open(struct net_device *netde + struct zd_chip *chip = &mac->chip; + int r; + ++ tasklet_enable(&mac->rx_tasklet); ++ + r = zd_chip_enable_int(chip); + if (r < 0) + goto out; +@@ -210,6 +220,8 @@ int zd_mac_stop(struct net_device *netde + */ + + zd_chip_disable_rx(chip); ++ skb_queue_purge(&mac->rx_queue); ++ tasklet_disable(&mac->rx_tasklet); + housekeeping_disable(mac); + ieee80211softmac_stop(netdev); + +@@ -873,45 +885,78 @@ static int fill_rx_stats(struct ieee8021 + return 0; + } + +-int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length) ++static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) + { + int r; + struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); + struct ieee80211_rx_stats stats; + const struct rx_status *status; +- struct sk_buff *skb; + +- if (length < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + +- IEEE80211_FCS_LEN + sizeof(struct rx_status)) +- return -EINVAL; ++ if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + ++ IEEE80211_FCS_LEN + sizeof(struct rx_status)) ++ { ++ dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", ++ skb->len); ++ goto free_skb; ++ } + +- r = fill_rx_stats(&stats, &status, mac, buffer, length); +- if (r) +- return r; ++ r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); ++ if (r) { ++ /* Only packets with rx errors are included here. */ ++ goto free_skb; ++ } + +- length -= ZD_PLCP_HEADER_SIZE+IEEE80211_FCS_LEN+ +- sizeof(struct rx_status); +- buffer += ZD_PLCP_HEADER_SIZE; ++ __skb_pull(skb, ZD_PLCP_HEADER_SIZE); ++ __skb_trim(skb, skb->len - ++ (IEEE80211_FCS_LEN + sizeof(struct rx_status))); + +- update_qual_rssi(mac, buffer, length, stats.signal, stats.rssi); ++ update_qual_rssi(mac, skb->data, skb->len, stats.signal, ++ status->signal_strength); + +- r = filter_rx(ieee, buffer, length, &stats); +- if (r <= 0) +- return r; + +- skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); +- if (!skb) +- return -ENOMEM; ++ r = filter_rx(ieee, skb->data, skb->len, &stats); ++ if (r <= 0) { ++ if (r < 0) ++ dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); ++ goto free_skb; ++ } ++ + if (ieee->iw_mode == IW_MODE_MONITOR) +- fill_rt_header(skb_put(skb, sizeof(struct zd_rt_hdr)), mac, ++ fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, + &stats, status); +- memcpy(skb_put(skb, length), buffer, length); + + r = ieee80211_rx(ieee, skb, &stats); +- if (!r) { +- ZD_ASSERT(in_irq()); +- dev_kfree_skb_irq(skb); ++ if (r) ++ return; ++ ++free_skb: ++ /* We are always in a soft irq. */ ++ dev_kfree_skb(skb); ++} ++ ++static void do_rx(unsigned long mac_ptr) ++{ ++ struct zd_mac *mac = (struct zd_mac *)mac_ptr; ++ struct sk_buff *skb; ++ ++ while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) ++ zd_mac_rx(mac, skb); ++} ++ ++int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) ++{ ++ struct sk_buff *skb; ++ ++ skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); ++ if (!skb) { ++ dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); ++ return -ENOMEM; + } ++ skb_reserve(skb, sizeof(struct zd_rt_hdr)); ++ memcpy(__skb_put(skb, length), buffer, length); ++ skb_queue_tail(&mac->rx_queue, skb); ++ tasklet_schedule(&mac->rx_tasklet); ++ + return 0; + } + +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_mac.h ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_mac.h +@@ -133,6 +133,10 @@ struct zd_mac { + /* Unlocked reading possible */ + struct iw_statistics iw_stats; + struct housekeeping housekeeping; ++ ++ struct tasklet_struct rx_tasklet; ++ struct sk_buff_head rx_queue; ++ + unsigned int stats_count; + u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; + u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; +@@ -174,7 +178,7 @@ int zd_mac_open(struct net_device *netde + int zd_mac_stop(struct net_device *netdev); + int zd_mac_set_mac_address(struct net_device *dev, void *p); + +-int zd_mac_rx(struct zd_mac *mac, const u8 *buffer, unsigned int length); ++int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); + + int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); + u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); +--- linux-2.6.19.1.orig/drivers/net/wireless/zd1211rw/zd_usb.c ++++ linux-2.6.19.1/drivers/net/wireless/zd1211rw/zd_usb.c +@@ -599,13 +599,13 @@ static void handle_rx_packet(struct zd_u + n = l+k; + if (n > length) + return; +- zd_mac_rx(mac, buffer+l, k); ++ zd_mac_rx_irq(mac, buffer+l, k); + if (i >= 2) + return; + l = (n+3) & ~3; + } + } else { +- zd_mac_rx(mac, buffer, length); ++ zd_mac_rx_irq(mac, buffer, length); + } + } +