This is the start of the stable review cycle for the 2.6.19.5 release.
This will probably be the last release of the 2.6.19-stable series, so
if there are patches that you feel should be applied to that tree,
please let me know.
There are 21 patches in this series, all will be posted as a response to
this one. If anyone has any issues with these being applied, please let
us know. If anyone is a maintainer of the proper subsystem, and wants
to add a Signed-off-by: line to the patch, please respond with it.
These patches are sent out with a number of different people on the Cc:
line. If you wish to be a reviewer, please email [email protected] to
add your name to the list. If you want to be off the reviewer list,
also email us.
Responses should be made by Friday February 23 00:00 UTC. Anything
received after that time might be too late.
The whole patch set can be downloaded at:
kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.19.5-rc1.gz
thanks,
the -stable release team
-stable review patch. If anyone has any objections, please let us know.
------------------
Host endianess does not affect the order that pixel rgb data comes
in from the quickcam (the values are bytes, not words or longs). The
driver is erroniously swapping the order of rgb values for big endian
machines. This patch is needed get the Quickcam communicator working
on big endian machines (tested on powerpc)
(cherry picked from commit c6d704c8c4453f05717ba88792f70f8babf95268)
Signed-off-by: Grant Likely <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Michael Krufky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/video/usbvideo/quickcam_messenger.h | 14 --------------
1 file changed, 14 deletions(-)
--- linux-2.6.19.4.orig/drivers/media/video/usbvideo/quickcam_messenger.h
+++ linux-2.6.19.4/drivers/media/video/usbvideo/quickcam_messenger.h
@@ -35,27 +35,13 @@ struct rgb {
};
struct bayL0 {
-#ifdef __BIG_ENDIAN
- u8 r;
- u8 g;
-#elif __LITTLE_ENDIAN
u8 g;
u8 r;
-#else
-#error not byte order defined
-#endif
};
struct bayL1 {
-#ifdef __BIG_ENDIAN
- u8 g;
- u8 b;
-#elif __LITTLE_ENDIAN
u8 b;
u8 g;
-#else
-#error not byte order defined
-#endif
};
struct cam_size {
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Peter Korsgaard <[email protected]>
smc911x_phy_configure's error handling unconditionally unlocks the
spinlock even if it wasn't locked. Patch fixes it.
Signed-off-by: Peter Korsgaard <[email protected]>
Cc: Jeff Garzik <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/smc911x.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- linux-2.6.19.4.orig/drivers/net/smc911x.c
+++ linux-2.6.19.4/drivers/net/smc911x.c
@@ -965,11 +965,11 @@ static void smc911x_phy_configure(void *
* We should not be called if phy_type is zero.
*/
if (lp->phy_type == 0)
- goto smc911x_phy_configure_exit;
+ goto smc911x_phy_configure_exit_nolock;
if (smc911x_phy_reset(dev, phyaddr)) {
printk("%s: PHY reset timed out\n", dev->name);
- goto smc911x_phy_configure_exit;
+ goto smc911x_phy_configure_exit_nolock;
}
spin_lock_irqsave(&lp->lock, flags);
@@ -1038,6 +1038,7 @@ static void smc911x_phy_configure(void *
smc911x_phy_configure_exit:
spin_unlock_irqrestore(&lp->lock, flags);
+smc911x_phy_configure_exit_nolock:
lp->work_pending = 0;
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
We are doing ->buf_prepare(buf) before adding buf to q->stream list. This
means that videobuf_qbuf() should not try to re-add a STATE_PREPARED buffer.
(cherry picked from commit 419dd8378dfa32985672ab7927b4bc827f33b332)
Signed-off-by: Oleg Nesterov <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Michael Krufky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/video/video-buf.c | 1 +
1 file changed, 1 insertion(+)
--- linux-2.6.19.4.orig/drivers/media/video/video-buf.c
+++ linux-2.6.19.4/drivers/media/video/video-buf.c
@@ -700,6 +700,7 @@ videobuf_qbuf(struct videobuf_queue *q,
goto done;
}
if (buf->state == STATE_QUEUED ||
+ buf->state == STATE_PREPARED ||
buf->state == STATE_ACTIVE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Or status flags together in DECODER_GET_STATUS instead of and-zapping them.
(cherry picked from commit 55d5440d4587454628a850ce26703639885af678)
Signed-off-by: Martin Samuelsson <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Michael Krufky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/video/ks0127.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- linux-2.6.19.4.orig/drivers/media/video/ks0127.c
+++ linux-2.6.19.4/drivers/media/video/ks0127.c
@@ -712,13 +712,13 @@ static int ks0127_command(struct i2c_cli
*iarg = 0;
status = ks0127_read(ks, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
- *iarg = (*iarg & DECODER_STATUS_GOOD);
+ *iarg = (*iarg | DECODER_STATUS_GOOD);
if ((status & 0x01)) /* CLOCK set */
- *iarg = (*iarg & DECODER_STATUS_COLOR);
+ *iarg = (*iarg | DECODER_STATUS_COLOR);
if ((status & 0x08)) /* PALDET set */
- *iarg = (*iarg & DECODER_STATUS_PAL);
+ *iarg = (*iarg | DECODER_STATUS_PAL);
else
- *iarg = (*iarg & DECODER_STATUS_NTSC);
+ *iarg = (*iarg | DECODER_STATUS_NTSC);
break;
//Catch any unknown command
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Autodetect LG TAPC G701D as tuner type 37, fixing
mis-detected tuners in some Hauppauge tv tuner cards.
Thanks to Adonis Papas, for pointing this out.
(cherry picked from commit 1323fbda1343f50f198bc8bd6d1d59c8b7fc45bf)
Signed-off-by: Michael Krufky <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/video/tveeprom.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-2.6.19.4.orig/drivers/media/video/tveeprom.c
+++ linux-2.6.19.4/drivers/media/video/tveeprom.c
@@ -184,7 +184,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Thompson DTT757"},
/* 80-89 */
{ TUNER_ABSENT, "Philips FQ1216LME MK3"},
- { TUNER_ABSENT, "LG TAPC G701D"},
+ { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
{ TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: "Ken Chen" <[email protected]>
An AIO bug was reported that sleeping function is being called in softirq
context:
BUG: warning at kernel/mutex.c:132/__mutex_lock_common()
Call Trace:
[<a000000100577b00>] __mutex_lock_slowpath+0x640/0x6c0
[<a000000100577ba0>] mutex_lock+0x20/0x40
[<a0000001000a25b0>] flush_workqueue+0xb0/0x1a0
[<a00000010018c0c0>] __put_ioctx+0xc0/0x240
[<a00000010018d470>] aio_complete+0x2f0/0x420
[<a00000010019cc80>] finished_one_bio+0x200/0x2a0
[<a00000010019d1c0>] dio_bio_complete+0x1c0/0x200
[<a00000010019d260>] dio_bio_end_aio+0x60/0x80
[<a00000010014acd0>] bio_endio+0x110/0x1c0
[<a0000001002770e0>] __end_that_request_first+0x180/0xba0
[<a000000100277b90>] end_that_request_chunk+0x30/0x60
[<a0000002073c0c70>] scsi_end_request+0x50/0x300 [scsi_mod]
[<a0000002073c1240>] scsi_io_completion+0x200/0x8a0 [scsi_mod]
[<a0000002074729b0>] sd_rw_intr+0x330/0x860 [sd_mod]
[<a0000002073b3ac0>] scsi_finish_command+0x100/0x1c0 [scsi_mod]
[<a0000002073c2910>] scsi_softirq_done+0x230/0x300 [scsi_mod]
[<a000000100277d20>] blk_done_softirq+0x160/0x1c0
[<a000000100083e00>] __do_softirq+0x200/0x240
[<a000000100083eb0>] do_softirq+0x70/0xc0
See report: http://marc.theaimsgroup.com/?l=linux-kernel&m=116599593200888&w=2
flush_workqueue() is not allowed to be called in the softirq context.
However, aio_complete() called from I/O interrupt can potentially call
put_ioctx with last ref count on ioctx and triggers bug. It is simply
incorrect to perform ioctx freeing from aio_complete.
The bug is trigger-able from a race between io_destroy() and aio_complete().
A possible scenario:
cpu0 cpu1
io_destroy aio_complete
wait_for_all_aios { __aio_put_req
... ctx->reqs_active--;
if (!ctx->reqs_active)
return;
}
...
put_ioctx(ioctx)
put_ioctx(ctx);
__put_ioctx
bam! Bug trigger!
The real problem is that the condition check of ctx->reqs_active in
wait_for_all_aios() is incorrect that access to reqs_active is not
being properly protected by spin lock.
This patch adds that protective spin lock, and at the same time removes
all duplicate ref counting for each kiocb as reqs_active is already used
as a ref count for each active ioctx. This also ensures that buggy call
to flush_workqueue() in softirq context is eliminated.
Signed-off-by: "Ken Chen" <[email protected]>
Cc: Zach Brown <[email protected]>
Cc: Suparna Bhattacharya <[email protected]>
Cc: Benjamin LaHaise <[email protected]>
Cc: Badari Pulavarty <[email protected]>
Acked-by: Jeff Moyer <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/aio.c | 20 +++++++++-----------
1 file changed, 9 insertions(+), 11 deletions(-)
--- linux-2.6.19.4.orig/fs/aio.c
+++ linux-2.6.19.4/fs/aio.c
@@ -298,17 +298,23 @@ static void wait_for_all_aios(struct kio
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
+ spin_lock_irq(&ctx->ctx_lock);
if (!ctx->reqs_active)
- return;
+ goto out;
add_wait_queue(&ctx->wait, &wait);
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
while (ctx->reqs_active) {
+ spin_unlock_irq(&ctx->ctx_lock);
schedule();
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ spin_lock_irq(&ctx->ctx_lock);
}
__set_task_state(tsk, TASK_RUNNING);
remove_wait_queue(&ctx->wait, &wait);
+
+out:
+ spin_unlock_irq(&ctx->ctx_lock);
}
/* wait_on_sync_kiocb:
@@ -425,7 +431,6 @@ static struct kiocb fastcall *__aio_get_
ring = kmap_atomic(ctx->ring_info.ring_pages[0], KM_USER0);
if (ctx->reqs_active < aio_ring_avail(&ctx->ring_info, ring)) {
list_add(&req->ki_list, &ctx->active_reqs);
- get_ioctx(ctx);
ctx->reqs_active++;
okay = 1;
}
@@ -538,8 +543,6 @@ int fastcall aio_put_req(struct kiocb *r
spin_lock_irq(&ctx->ctx_lock);
ret = __aio_put_req(ctx, req);
spin_unlock_irq(&ctx->ctx_lock);
- if (ret)
- put_ioctx(ctx);
return ret;
}
@@ -795,8 +798,7 @@ static int __aio_run_iocbs(struct kioctx
*/
iocb->ki_users++; /* grab extra reference */
aio_run_iocb(iocb);
- if (__aio_put_req(ctx, iocb)) /* drop extra ref */
- put_ioctx(ctx);
+ __aio_put_req(ctx, iocb);
}
if (!list_empty(&ctx->run_list))
return 1;
@@ -1014,14 +1016,10 @@ put_rq:
/* everything turned out well, dispose of the aiocb. */
ret = __aio_put_req(ctx, iocb);
- spin_unlock_irqrestore(&ctx->ctx_lock, flags);
-
if (waitqueue_active(&ctx->wait))
wake_up(&ctx->wait);
- if (ret)
- put_ioctx(ctx);
-
+ spin_unlock_irqrestore(&ctx->ctx_lock, flags);
return ret;
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
[PATCH] usb-audio: work around wrong frequency in CM6501 descriptors
The C-Media CM6501 chip's descriptors say that altsetting 5 supports
48 kHz, but it actually plays at 96 kHz.
Signed-off-by: Clemens Ladisch <[email protected]>
Signed-off-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/usb/usbaudio.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- linux-2.6.19.4.orig/sound/usb/usbaudio.c
+++ linux-2.6.19.4/sound/usb/usbaudio.c
@@ -2471,7 +2471,13 @@ static int parse_audio_format_rates(stru
fp->nr_rates = nr_rates;
fp->rate_min = fp->rate_max = combine_triple(&fmt[8]);
for (r = 0, idx = offset + 1; r < nr_rates; r++, idx += 3) {
- unsigned int rate = fp->rate_table[r] = combine_triple(&fmt[idx]);
+ unsigned int rate = combine_triple(&fmt[idx]);
+ /* C-Media CM6501 mislabels its 96 kHz altsetting */
+ if (rate == 48000 && nr_rates == 1 &&
+ chip->usb_id == USB_ID(0x0d8c, 0x0201) &&
+ fp->altsetting == 5 && fp->maxpacksize == 392)
+ rate = 96000;
+ fp->rate_table[r] = rate;
if (rate < fp->rate_min)
fp->rate_min = rate;
else if (rate > fp->rate_max)
--
-stable review patch. If anyone has any objections, please let us know.
------------------
[PATCH] usbaudio - Fix Oops with broken usb descriptors
This is a patch for ALSA Bug #2724. Some webcams provide bogus
settings with no valid rates. With this patch those are skipped.
Signed-off-by: Gregor Jasny <[email protected]>
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jaroslav Kysela <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/usb/usbaudio.c | 6 ++++++
1 file changed, 6 insertions(+)
--- linux-2.6.19.4.orig/sound/usb/usbaudio.c
+++ linux-2.6.19.4/sound/usb/usbaudio.c
@@ -2456,6 +2456,7 @@ static int parse_audio_format_rates(stru
* build the rate table and bitmap flags
*/
int r, idx, c;
+ unsigned int nonzero_rates = 0;
/* this table corresponds to the SNDRV_PCM_RATE_XXX bit */
static unsigned int conv_rates[] = {
5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000,
@@ -2478,6 +2479,7 @@ static int parse_audio_format_rates(stru
fp->altsetting == 5 && fp->maxpacksize == 392)
rate = 96000;
fp->rate_table[r] = rate;
+ nonzero_rates |= rate;
if (rate < fp->rate_min)
fp->rate_min = rate;
else if (rate > fp->rate_max)
@@ -2493,6 +2495,10 @@ static int parse_audio_format_rates(stru
if (!found)
fp->needs_knot = 1;
}
+ if (!nonzero_rates) {
+ hwc_debug("All rates were zero. Skipping format!\n");
+ return -1;
+ }
if (fp->needs_knot)
fp->rates |= SNDRV_PCM_RATE_KNOT;
} else {
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ingo Molnar <[email protected]>
[PATCH] net, 8139too.c: fix netpoll deadlock
fix deadlock in the 8139too driver: poll handlers should never forcibly
enable local interrupts, because they might be used by netpoll/printk
from IRQ context.
=================================
[ INFO: inconsistent lock state ]
2.6.19 #11
---------------------------------
inconsistent {softirq-on-W} -> {in-softirq-W} usage.
swapper/1 [HC0[0]:SC1[1]:HE1:SE0] takes:
(&npinfo->poll_lock){-+..}, at: [<c0350a41>] net_rx_action+0x64/0x1de
{softirq-on-W} state was registered at:
[<c0134c86>] mark_lock+0x5b/0x39c
[<c0135012>] mark_held_locks+0x4b/0x68
[<c01351e9>] trace_hardirqs_on+0x115/0x139
[<c02879e6>] rtl8139_poll+0x3d7/0x3f4
[<c035c85d>] netpoll_poll+0x82/0x32f
[<c035c775>] netpoll_send_skb+0xc9/0x12f
[<c035cdcc>] netpoll_send_udp+0x253/0x25b
[<c0288463>] write_msg+0x40/0x65
[<c011cead>] __call_console_drivers+0x45/0x51
[<c011cf16>] _call_console_drivers+0x5d/0x61
[<c011d4fb>] release_console_sem+0x11f/0x1d8
[<c011d7d7>] register_console+0x1ac/0x1b3
[<c02883f8>] init_netconsole+0x55/0x67
[<c010040c>] init+0x9a/0x24e
[<c01049cf>] kernel_thread_helper+0x7/0x10
[<ffffffff>] 0xffffffff
irq event stamp: 819992
hardirqs last enabled at (819992): [<c0350a16>] net_rx_action+0x39/0x1de
hardirqs last disabled at (819991): [<c0350b1e>] net_rx_action+0x141/0x1de
softirqs last enabled at (817552): [<c01214e4>] __do_softirq+0xa3/0xa8
softirqs last disabled at (819987): [<c0106051>] do_softirq+0x5b/0xc9
other info that might help us debug this:
no locks held by swapper/1.
stack backtrace:
[<c0104d88>] dump_trace+0x63/0x1e8
[<c0104f26>] show_trace_log_lvl+0x19/0x2e
[<c010532d>] show_trace+0x12/0x14
[<c0105343>] dump_stack+0x14/0x16
[<c0134980>] print_usage_bug+0x23c/0x246
[<c0134d33>] mark_lock+0x108/0x39c
[<c01356a7>] __lock_acquire+0x361/0x9ed
[<c0136018>] lock_acquire+0x56/0x72
[<c03aff1f>] _spin_lock+0x35/0x42
[<c0350a41>] net_rx_action+0x64/0x1de
[<c0121493>] __do_softirq+0x52/0xa8
[<c0106051>] do_softirq+0x5b/0xc9
[<c0121338>] irq_exit+0x3c/0x48
[<c0106163>] do_IRQ+0xa4/0xbd
[<c01047c6>] common_interrupt+0x2e/0x34
[<c011db92>] vprintk+0x2c0/0x309
[<c011dbf6>] printk+0x1b/0x1d
[<c01003f2>] init+0x80/0x24e
[<c01049cf>] kernel_thread_helper+0x7/0x10
=======================
Signed-off-by: Ingo Molnar <[email protected]>
Acked-by: Jeff Garzik <[email protected]>
Cc: Chuck Ebbert <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/8139too.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- linux-2.6.19.4.orig/drivers/net/8139too.c
+++ linux-2.6.19.4/drivers/net/8139too.c
@@ -2129,14 +2129,15 @@ static int rtl8139_poll(struct net_devic
}
if (done) {
+ unsigned long flags;
/*
* Order is important since data can get interrupted
* again when we think we are done.
*/
- local_irq_disable();
+ local_irq_save(flags);
RTL_W16_F(IntrMask, rtl8139_intr_mask);
__netif_rx_complete(dev);
- local_irq_enable();
+ local_irq_restore(flags);
}
spin_unlock(&tp->rx_lock);
--
-stable review patch. If anyone has any objections, please let us know.
------------------
eighty_ninty_three() had word 93 validitity check but not the 80c bit
test itself (bit 12). This increases the chance of incorrect wire
detection especially because host side cable detection is often
unreliable and we sometimes soley depend on drive side cable
detection. Fix it.
Signed-off-by: Tejun Heo <[email protected]>
Acked-by: Alan <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/ide/ide-iops.c | 2 ++
1 file changed, 2 insertions(+)
--- linux-2.6.19.4.orig/drivers/ide/ide-iops.c
+++ linux-2.6.19.4/drivers/ide/ide-iops.c
@@ -607,6 +607,8 @@ u8 eighty_ninty_three (ide_drive_t *driv
if(!(drive->id->hw_config & 0x4000))
return 0;
#endif /* CONFIG_IDEDMA_IVB */
+ if (!(drive->id->hw_config & 0x2000))
+ return 0;
return 1;
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
If you lose this race, it can iput a socket inode twice and you
get a BUG in fs/inode.c
When I added the option for user-space to close a socket,
I added some cruft to svc_delete_socket so that I could call
that function when closing a socket per user-space request.
This was the wrong thing to do. I should have just set SK_CLOSE
and let normal mechanisms do the work.
Not only wrong, but buggy. The locking is all wrong and it openned
up a race where-by a socket could be closed twice.
So this patch:
Introduces svc_close_socket which sets SK_CLOSE then either leave
the close up to a thread, or calls svc_delete_socket if it can
get SK_BUSY.
Adds a bias to sk_busy which is removed when SK_DEAD is set,
This avoid races around shutting down the socket.
Changes several 'spin_lock' to 'spin_lock_bh' where the _bh
was missing.
Bugzilla-url: http://bugzilla.kernel.org/show_bug.cgi?id=7916
Signed-off-by: Neil Brown <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/linux/sunrpc/svcsock.h | 2 -
net/sunrpc/svc.c | 4 +--
net/sunrpc/svcsock.c | 52 +++++++++++++++++++++++++++++------------
3 files changed, 41 insertions(+), 17 deletions(-)
--- linux-2.6.19.4.orig/include/linux/sunrpc/svcsock.h
+++ linux-2.6.19.4/include/linux/sunrpc/svcsock.h
@@ -63,7 +63,7 @@ struct svc_sock {
* Function prototypes.
*/
int svc_makesock(struct svc_serv *, int, unsigned short);
-void svc_delete_socket(struct svc_sock *);
+void svc_close_socket(struct svc_sock *);
int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);
--- linux-2.6.19.4.orig/net/sunrpc/svc.c
+++ linux-2.6.19.4/net/sunrpc/svc.c
@@ -387,7 +387,7 @@ svc_destroy(struct svc_serv *serv)
svsk = list_entry(serv->sv_tempsocks.next,
struct svc_sock,
sk_list);
- svc_delete_socket(svsk);
+ svc_close_socket(svsk);
}
if (serv->sv_shutdown)
serv->sv_shutdown(serv);
@@ -396,7 +396,7 @@ svc_destroy(struct svc_serv *serv)
svsk = list_entry(serv->sv_permsocks.next,
struct svc_sock,
sk_list);
- svc_delete_socket(svsk);
+ svc_close_socket(svsk);
}
cache_clean_deferred(serv);
--- linux-2.6.19.4.orig/net/sunrpc/svcsock.c
+++ linux-2.6.19.4/net/sunrpc/svcsock.c
@@ -61,6 +61,12 @@
* after a clear, the socket must be read/accepted
* if this succeeds, it must be set again.
* SK_CLOSE can set at any time. It is never cleared.
+ * sk_inuse contains a bias of '1' until SK_DEAD is set.
+ * so when sk_inuse hits zero, we know the socket is dead
+ * and no-one is using it.
+ * SK_DEAD can only be set while SK_BUSY is held which ensures
+ * no other thread will be using the socket or will try to
+ * set SK_DEAD.
*
*/
@@ -69,6 +75,7 @@
static struct svc_sock *svc_setup_socket(struct svc_serv *, struct socket *,
int *errp, int pmap_reg);
+static void svc_delete_socket(struct svc_sock *svsk);
static void svc_udp_data_ready(struct sock *, int);
static int svc_udp_recvfrom(struct svc_rqst *);
static int svc_udp_sendto(struct svc_rqst *);
@@ -299,8 +306,9 @@ void svc_reserve(struct svc_rqst *rqstp,
static inline void
svc_sock_put(struct svc_sock *svsk)
{
- if (atomic_dec_and_test(&svsk->sk_inuse) &&
- test_bit(SK_DEAD, &svsk->sk_flags)) {
+ if (atomic_dec_and_test(&svsk->sk_inuse)) {
+ BUG_ON(! test_bit(SK_DEAD, &svsk->sk_flags));
+
dprintk("svc: releasing dead socket\n");
if (svsk->sk_sock->file)
sockfd_put(svsk->sk_sock);
@@ -490,7 +498,7 @@ svc_sock_names(char *buf, struct svc_ser
if (!serv)
return 0;
- spin_lock(&serv->sv_lock);
+ spin_lock_bh(&serv->sv_lock);
list_for_each_entry(svsk, &serv->sv_permsocks, sk_list) {
int onelen = one_sock_name(buf+len, svsk);
if (toclose && strcmp(toclose, buf+len) == 0)
@@ -498,12 +506,12 @@ svc_sock_names(char *buf, struct svc_ser
else
len += onelen;
}
- spin_unlock(&serv->sv_lock);
+ spin_unlock_bh(&serv->sv_lock);
if (closesk)
/* Should unregister with portmap, but you cannot
* unregister just one protocol...
*/
- svc_delete_socket(closesk);
+ svc_close_socket(closesk);
else if (toclose)
return -ENOENT;
return len;
@@ -653,6 +661,11 @@ svc_udp_recvfrom(struct svc_rqst *rqstp)
return svc_deferred_recv(rqstp);
}
+ if (test_bit(SK_CLOSE, &svsk->sk_flags)) {
+ svc_delete_socket(svsk);
+ return 0;
+ }
+
clear_bit(SK_DATA, &svsk->sk_flags);
while ((skb = skb_recv_datagram(svsk->sk_sk, 0, 1, &err)) == NULL) {
if (err == -EAGAIN) {
@@ -1142,7 +1155,8 @@ svc_tcp_sendto(struct svc_rqst *rqstp)
rqstp->rq_sock->sk_server->sv_name,
(sent<0)?"got error":"sent only",
sent, xbufp->len);
- svc_delete_socket(rqstp->rq_sock);
+ set_bit(SK_CLOSE, &rqstp->rq_sock->sk_flags);
+ svc_sock_enqueue(rqstp->rq_sock);
sent = -EAGAIN;
}
return sent;
@@ -1461,7 +1475,7 @@ svc_setup_socket(struct svc_serv *serv,
svsk->sk_odata = inet->sk_data_ready;
svsk->sk_owspace = inet->sk_write_space;
svsk->sk_server = serv;
- atomic_set(&svsk->sk_inuse, 0);
+ atomic_set(&svsk->sk_inuse, 1);
svsk->sk_lastrecv = get_seconds();
spin_lock_init(&svsk->sk_defer_lock);
INIT_LIST_HEAD(&svsk->sk_deferred);
@@ -1582,7 +1596,7 @@ bummer:
/*
* Remove a dead socket
*/
-void
+static void
svc_delete_socket(struct svc_sock *svsk)
{
struct svc_serv *serv;
@@ -1608,16 +1622,26 @@ svc_delete_socket(struct svc_sock *svsk)
* while still attached to a queue, the queue itself
* is about to be destroyed (in svc_destroy).
*/
- if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags))
+ if (!test_and_set_bit(SK_DEAD, &svsk->sk_flags)) {
+ BUG_ON(atomic_read(&svsk->sk_inuse)<2);
+ atomic_dec(&svsk->sk_inuse);
if (test_bit(SK_TEMP, &svsk->sk_flags))
serv->sv_tmpcnt--;
+ }
- /* This atomic_inc should be needed - svc_delete_socket
- * should have the semantic of dropping a reference.
- * But it doesn't yet....
- */
- atomic_inc(&svsk->sk_inuse);
spin_unlock_bh(&serv->sv_lock);
+}
+
+void svc_close_socket(struct svc_sock *svsk)
+{
+ set_bit(SK_CLOSE, &svsk->sk_flags);
+ if (test_and_set_bit(SK_BUSY, &svsk->sk_flags))
+ /* someone else will have to effect the close */
+ return;
+
+ atomic_inc(&svsk->sk_inuse);
+ svc_delete_socket(svsk);
+ clear_bit(SK_BUSY, &svsk->sk_flags);
svc_sock_put(svsk);
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Howells <[email protected]>
[PATCH] Keys: Fix key serial number collision handling
Fix the key serial number collision avoidance code in key_alloc_serial().
This didn't use to be so much of a problem as the key serial numbers were
allocated from a simple incremental counter, and it would have to go through
two billion keys before it could possibly encounter a collision. However, now
that random numbers are used instead, collisions are much more likely.
This is fixed by finding a hole in the rbtree where the next unused serial
number ought to be and using that by going almost back to the top of the
insertion routine and redoing the insertion with the new serial number rather
than trying to be clever and attempting to work out the insertion point
pointer directly.
This fixes kernel BZ #7727.
Signed-off-by: David Howells <[email protected]>
Cc: Chuck Ebbert <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
security/keys/key.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
--- linux-2.6.19.4.orig/security/keys/key.c
+++ linux-2.6.19.4/security/keys/key.c
@@ -188,6 +188,7 @@ static inline void key_alloc_serial(stru
spin_lock(&key_serial_lock);
+attempt_insertion:
parent = NULL;
p = &key_serial_tree.rb_node;
@@ -202,39 +203,33 @@ static inline void key_alloc_serial(stru
else
goto serial_exists;
}
- goto insert_here;
+
+ /* we've found a suitable hole - arrange for this key to occupy it */
+ rb_link_node(&key->serial_node, parent, p);
+ rb_insert_color(&key->serial_node, &key_serial_tree);
+
+ spin_unlock(&key_serial_lock);
+ return;
/* we found a key with the proposed serial number - walk the tree from
* that point looking for the next unused serial number */
serial_exists:
for (;;) {
key->serial++;
- if (key->serial < 2)
- key->serial = 2;
-
- if (!rb_parent(parent))
- p = &key_serial_tree.rb_node;
- else if (rb_parent(parent)->rb_left == parent)
- p = &(rb_parent(parent)->rb_left);
- else
- p = &(rb_parent(parent)->rb_right);
+ if (key->serial < 3) {
+ key->serial = 3;
+ goto attempt_insertion;
+ }
parent = rb_next(parent);
if (!parent)
- break;
+ goto attempt_insertion;
xkey = rb_entry(parent, struct key, serial_node);
if (key->serial < xkey->serial)
- goto insert_here;
+ goto attempt_insertion;
}
- /* we've found a suitable hole - arrange for this key to occupy it */
-insert_here:
- rb_link_node(&key->serial_node, parent, p);
- rb_insert_color(&key->serial_node, &key_serial_tree);
-
- spin_unlock(&key_serial_lock);
-
} /* end key_alloc_serial() */
/*****************************************************************************/
--
-stable review patch. If anyone has any objections, please let us know.
------------------
[PATCH] usbaudio - Fix Oops with unconventional sample rates
The patch fixes the memory corruption by the support of unconventional
sample rates. Also, it avoids the too restrictive constraints if
any of usb descriptions contain continuous rates.
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
sound/usb/usbaudio.c | 43 +++++++++++++++++++++++++------------------
1 file changed, 25 insertions(+), 18 deletions(-)
--- linux-2.6.19.4.orig/sound/usb/usbaudio.c
+++ linux-2.6.19.4/sound/usb/usbaudio.c
@@ -186,6 +186,7 @@ struct snd_usb_substream {
u64 formats; /* format bitmasks (all or'ed) */
unsigned int num_formats; /* number of supported audio formats (list) */
struct list_head fmt_list; /* format list */
+ struct snd_pcm_hw_constraint_list rate_list; /* limited rates */
spinlock_t lock;
struct snd_urb_ops ops; /* callbacks (must be filled at init) */
@@ -1810,28 +1811,33 @@ static int check_hw_params_convention(st
static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime,
struct snd_usb_substream *subs)
{
- struct list_head *p;
- struct snd_pcm_hw_constraint_list constraints_rates;
+ struct audioformat *fp;
+ int count = 0, needs_knot = 0;
int err;
- list_for_each(p, &subs->fmt_list) {
- struct audioformat *fp;
- fp = list_entry(p, struct audioformat, list);
-
- if (!fp->needs_knot)
- continue;
-
- constraints_rates.count = fp->nr_rates;
- constraints_rates.list = fp->rate_table;
- constraints_rates.mask = 0;
-
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &constraints_rates);
+ list_for_each_entry(fp, &subs->fmt_list, list) {
+ if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS)
+ return 0;
+ count += fp->nr_rates;
+ if (fp->needs_knot)
+ needs_knot = 1;
+ }
+ if (!needs_knot)
+ return 0;
- if (err < 0)
- return err;
+ subs->rate_list.count = count;
+ subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL);
+ subs->rate_list.mask = 0;
+ count = 0;
+ list_for_each_entry(fp, &subs->fmt_list, list) {
+ int i;
+ for (i = 0; i < fp->nr_rates; i++)
+ subs->rate_list.list[count++] = fp->rate_table[i];
}
+ err = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ &subs->rate_list);
+ if (err < 0)
+ return err;
return 0;
}
@@ -2231,6 +2237,7 @@ static void free_substream(struct snd_us
kfree(fp->rate_table);
kfree(fp);
}
+ kfree(subs->rate_list.list);
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Correct assignment of DOT1XENABLE in WE-19 codepaths.
RX_UNENCRYPTED_EAPOL = 1 really means setting DOT1XENABLE _off_, and
vice versa. The original WE-19 patch erroneously reversed that. This
patch fixes association with unencrypted and WEP networks when using
wpa_supplicant.
It also adds two missing break statements that, left out, could result
in incorrect card configuration.
Applies to (I think) 2.6.19 and later.
Signed-off-by: Dan Williams <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/prism54/isl_ioctl.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- linux-2.6.19.4.orig/drivers/net/wireless/prism54/isl_ioctl.c
+++ linux-2.6.19.4/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1395,11 +1395,16 @@ static int prism54_set_auth(struct net_d
break;
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- dot1x = param->value ? 1 : 0;
+ /* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
+ * turn off dot1x when allowing recepit of unencrypted eapol
+ * frames, turn on dot1x when we disallow receipt
+ */
+ dot1x = param->value ? 0x00 : 0x01;
break;
case IW_AUTH_PRIVACY_INVOKED:
privinvoked = param->value ? 1 : 0;
+ break;
case IW_AUTH_DROP_UNENCRYPTED:
exunencrypt = param->value ? 1 : 0;
@@ -1589,6 +1594,7 @@ static int prism54_set_encodeext(struct
}
key.type = DOT11_PRIV_TKIP;
key.length = KEY_SIZE_TKIP;
+ break;
default:
return -EINVAL;
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Use different constraint for gcc < 4.1 in bitops.h
+m is really correct for a RMW instruction, but some older gccs
error out. I finally gave in and ifdefed it.
This fixes compilation errors with some compiler version.
Signed-off-by: Andi Kleen <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
include/asm-x86_64/bitops.h | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
--- linux-2.6.19.4.orig/include/asm-x86_64/bitops.h
+++ linux-2.6.19.4/include/asm-x86_64/bitops.h
@@ -7,7 +7,13 @@
#include <asm/alternative.h>
-#define ADDR (*(volatile long *) addr)
+#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 1)
+/* Technically wrong, but this avoids compilation errors on some gcc
+ versions. */
+#define ADDR "=m" (*(volatile long *) addr)
+#else
+#define ADDR "+m" (*(volatile long *) addr)
+#endif
/**
* set_bit - Atomically set a bit in memory
@@ -23,7 +29,7 @@ static __inline__ void set_bit(int nr, v
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr) : "memory");
}
@@ -40,7 +46,7 @@ static __inline__ void __set_bit(int nr,
{
__asm__ volatile(
"btsl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr) : "memory");
}
@@ -58,7 +64,7 @@ static __inline__ void clear_bit(int nr,
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr));
}
@@ -66,7 +72,7 @@ static __inline__ void __clear_bit(int n
{
__asm__ __volatile__(
"btrl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr));
}
@@ -86,7 +92,7 @@ static __inline__ void __change_bit(int
{
__asm__ __volatile__(
"btcl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr));
}
@@ -103,7 +109,7 @@ static __inline__ void change_bit(int nr
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
- :"+m" (ADDR)
+ :ADDR
:"dIr" (nr));
}
@@ -121,7 +127,7 @@ static __inline__ int test_and_set_bit(i
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -141,7 +147,7 @@ static __inline__ int __test_and_set_bit
__asm__(
"btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr));
return oldbit;
}
@@ -160,7 +166,7 @@ static __inline__ int test_and_clear_bit
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -180,7 +186,7 @@ static __inline__ int __test_and_clear_b
__asm__(
"btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr));
return oldbit;
}
@@ -192,7 +198,7 @@ static __inline__ int __test_and_change_
__asm__ __volatile__(
"btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -211,7 +217,7 @@ static __inline__ int test_and_change_bi
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"+m" (ADDR)
+ :"=r" (oldbit),ADDR
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -237,7 +243,7 @@ static __inline__ int variable_test_bit(
__asm__ __volatile__(
"btl %2,%1\n\tsbbl %0,%0"
:"=r" (oldbit)
- :"m" (ADDR),"dIr" (nr));
+ :"m" (*(volatile long *)addr),"dIr" (nr));
return oldbit;
}
--
-stable review patch. If anyone has any objections, please let us know.
------------------
80c test mask is at bits 18 and 19 of EIDE Controller Configuration
not 22 and 23. Fix it.
Signed-off-by: Tejun Heo <[email protected]>
Acked-by: Alan Cox <[email protected]>
---
drivers/ata/pata_amd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- linux-2.6.19.4.orig/drivers/ata/pata_amd.c
+++ linux-2.6.19.4/drivers/ata/pata_amd.c
@@ -128,7 +128,7 @@ static void timing_setup(struct ata_port
static int amd_pre_reset(struct ata_port *ap)
{
- static const u32 bitmask[2] = {0x03, 0xC0};
+ static const u32 bitmask[2] = {0x03, 0x0C};
static const struct pci_bits amd_enable_bits[] = {
{ 0x40, 1, 0x02, 0x02 },
{ 0x40, 1, 0x01, 0x01 }
@@ -247,7 +247,7 @@ static void amd133_set_dmamode(struct at
*/
static int nv_pre_reset(struct ata_port *ap) {
- static const u8 bitmask[2] = {0x03, 0xC0};
+ static const u8 bitmask[2] = {0x03, 0x0C};
static const struct pci_bits nv_enable_bits[] = {
{ 0x50, 1, 0x02, 0x02 },
{ 0x50, 1, 0x01, 0x01 }
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Also PTRACE_OLDSETOPTIONS should be accepted, as done by kernel/ptrace.c and
forced by binary compatibility. UML/32bit breaks because of this - since it is wise
enough to use PTRACE_OLDSETOPTIONS to be binary compatible with 2.4 host
kernels.
Until 2.6.17 (commit f0f2d6536e3515b5b1b7ae97dc8f176860c8c2ce) we had:
default:
return sys_ptrace(request, pid, addr, data);
Instead here we have:
case PTRACE_GET_THREAD_AREA:
case ...:
return sys_ptrace(request, pid, addr, data);
default:
return -EINVAL;
This change was a style change - when a case is added, it must be explicitly
tested this way. In this case, not enough testing was done.
Cc: Andi Kleen <[email protected]>
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
arch/x86_64/ia32/ptrace32.c | 1 +
1 file changed, 1 insertion(+)
--- linux-2.6.19.4.orig/arch/x86_64/ia32/ptrace32.c
+++ linux-2.6.19.4/arch/x86_64/ia32/ptrace32.c
@@ -243,6 +243,7 @@ asmlinkage long sys32_ptrace(long reques
case PTRACE_SINGLESTEP:
case PTRACE_DETACH:
case PTRACE_SYSCALL:
+ case PTRACE_OLDSETOPTIONS:
case PTRACE_SETOPTIONS:
case PTRACE_SET_THREAD_AREA:
case PTRACE_GET_THREAD_AREA:
--
-stable review patch. If anyone has any objections, please let us know.
------------------
Suspending with the cx88xx module loaded causes the system to lock up
because the cx88_audio_thread kthread was missing a try_to_freeze()
call, which caused it to go into a tight loop and result in softlockup
when suspending. Fix that.
(cherry picked from commit a96afb3e9428f2e7463344f12dbc85faf08e2e09)
Signed-off-by: Robert Hancock <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>
Signed-off-by: Michael Krufky <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/media/video/cx88/cx88-tvaudio.c | 2 ++
1 file changed, 2 insertions(+)
--- linux-2.6.19.4.orig/drivers/media/video/cx88/cx88-tvaudio.c
+++ linux-2.6.19.4/drivers/media/video/cx88/cx88-tvaudio.c
@@ -38,6 +38,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/errno.h>
+#include <linux/freezer.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
@@ -974,6 +975,7 @@ int cx88_audio_thread(void *data)
msleep_interruptible(1000);
if (kthread_should_stop())
break;
+ try_to_freeze();
/* just monitor the audio status for now ... */
memset(&t, 0, sizeof(t));
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michael Buesch <[email protected]>
If bcm43xx were to process an afterburner (ampdu) status response, Linux would oops. The
ampdu and intermediate status bits are properly named.
Signed-off-by: Michael Buesch <[email protected]>
Signed-off-by: Larry Finger <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/bcm43xx/bcm43xx_main.c | 8 +++-----
drivers/net/wireless/bcm43xx/bcm43xx_xmit.h | 10 ++--------
2 files changed, 5 insertions(+), 13 deletions(-)
--- linux-2.6.19.4.orig/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ linux-2.6.19.4/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -1449,12 +1449,10 @@ static void handle_irq_transmit_status(s
bcm43xx_debugfs_log_txstat(bcm, &stat);
- if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
+ continue;
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
continue;
- if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
- //TODO: packet was not acked (was lost)
- }
- //TODO: There are more (unknown) flags to test. see bcm43xx_main.h
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_handle_xmitstatus(bcm, &stat);
--- linux-2.6.19.4.orig/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ linux-2.6.19.4/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -137,14 +137,8 @@ struct bcm43xx_xmitstatus {
u16 unknown; //FIXME
};
-#define BCM43xx_TXSTAT_FLAG_ACK 0x01
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
-#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
+#define BCM43xx_TXSTAT_FLAG_AMPDU 0x10
+#define BCM43xx_TXSTAT_FLAG_INTER 0x20
u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
--
-stable review patch. If anyone has any objections, please let us know.
------------------
There is a kernel oops on bcm43xx when resuming due to an overly tight timeout loop.
Signed-off-by: Larry Finger<[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/net/wireless/bcm43xx/bcm43xx.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-2.6.19.4.orig/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ linux-2.6.19.4/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -21,7 +21,7 @@
#define PFX KBUILD_MODNAME ": "
#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
-#define BCM43xx_IRQWAIT_MAX_RETRIES 50
+#define BCM43xx_IRQWAIT_MAX_RETRIES 100
#define BCM43xx_IO_SIZE 8192
--
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Atsushi Nemoto <[email protected]>
The usage of the century bit was inverted on 2.6.19 following to PCF8563's
description, but it was not match to usage suggested by RTC8564's
datasheet. Anyway what MO_C=1 means can vary on each platform. This patch
is to detect its polarity in get_datetime routine. The default value of
c_polarity is 0 (MO_C=1 means 19xx) so that this patch does not change
current behavior even if get_datetime was not called before set_datetime.
Signed-off-by: Atsushi Nemoto <[email protected]>
Cc: Jean-Baptiste Maneyrol <[email protected]>
Cc: David Brownell <[email protected]>
Cc: Alessandro Zummo <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
drivers/rtc/rtc-pcf8563.c | 40 ++++++++++++++++++++++++++++++++++------
1 file changed, 34 insertions(+), 6 deletions(-)
--- linux-2.6.19.4.orig/drivers/rtc/rtc-pcf8563.c
+++ linux-2.6.19.4/drivers/rtc/rtc-pcf8563.c
@@ -53,6 +53,25 @@ I2C_CLIENT_INSMOD;
#define PCF8563_SC_LV 0x80 /* low voltage */
#define PCF8563_MO_C 0x80 /* century */
+struct pcf8563 {
+ struct i2c_client client;
+ /*
+ * The meaning of MO_C bit varies by the chip type.
+ * From PCF8563 datasheet: this bit is toggled when the years
+ * register overflows from 99 to 00
+ * 0 indicates the century is 20xx
+ * 1 indicates the century is 19xx
+ * From RTC8564 datasheet: this bit indicates change of
+ * century. When the year digit data overflows from 99 to 00,
+ * this bit is set. By presetting it to 0 while still in the
+ * 20th century, it will be set in year 2000, ...
+ * There seems no reliable way to know how the system use this
+ * bit. So let's do it heuristically, assuming we are live in
+ * 1970...2069.
+ */
+ int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
+};
+
static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind);
static int pcf8563_detach(struct i2c_client *client);
@@ -62,6 +81,7 @@ static int pcf8563_detach(struct i2c_cli
*/
static int pcf8563_get_datetime(struct i2c_client *client, struct rtc_time *tm)
{
+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
unsigned char buf[13] = { PCF8563_REG_ST1 };
struct i2c_msg msgs[] = {
@@ -94,8 +114,12 @@ static int pcf8563_get_datetime(struct i
tm->tm_mday = BCD2BIN(buf[PCF8563_REG_DM] & 0x3F);
tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
- tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
- + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
+ tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR]);
+ if (tm->tm_year < 70)
+ tm->tm_year += 100; /* assume we are in 1970...2069 */
+ /* detect the polarity heuristically. see note above. */
+ pcf8563->c_polarity = (buf[PCF8563_REG_MO] & PCF8563_MO_C) ?
+ (tm->tm_year >= 100) : (tm->tm_year < 100);
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -114,6 +138,7 @@ static int pcf8563_get_datetime(struct i
static int pcf8563_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
int i, err;
unsigned char buf[9];
@@ -135,7 +160,7 @@ static int pcf8563_set_datetime(struct i
/* year and century */
buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
- if (tm->tm_year < 100)
+ if (pcf8563->c_polarity ? (tm->tm_year >= 100) : (tm->tm_year < 100))
buf[PCF8563_REG_MO] |= PCF8563_MO_C;
buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
@@ -248,6 +273,7 @@ static struct i2c_driver pcf8563_driver
static int pcf8563_probe(struct i2c_adapter *adapter, int address, int kind)
{
+ struct pcf8563 *pcf8563;
struct i2c_client *client;
struct rtc_device *rtc;
@@ -260,11 +286,12 @@ static int pcf8563_probe(struct i2c_adap
goto exit;
}
- if (!(client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL))) {
+ if (!(pcf8563 = kzalloc(sizeof(struct pcf8563), GFP_KERNEL))) {
err = -ENOMEM;
goto exit;
}
+ client = &pcf8563->client;
client->addr = address;
client->driver = &pcf8563_driver;
client->adapter = adapter;
@@ -301,7 +328,7 @@ exit_detach:
i2c_detach_client(client);
exit_kfree:
- kfree(client);
+ kfree(pcf8563);
exit:
return err;
@@ -309,6 +336,7 @@ exit:
static int pcf8563_detach(struct i2c_client *client)
{
+ struct pcf8563 *pcf8563 = container_of(client, struct pcf8563, client);
int err;
struct rtc_device *rtc = i2c_get_clientdata(client);
@@ -318,7 +346,7 @@ static int pcf8563_detach(struct i2c_cli
if ((err = i2c_detach_client(client)))
return err;
- kfree(client);
+ kfree(pcf8563);
return 0;
}
--
Greg KH wrote:
> This is the start of the stable review cycle for the 2.6.19.5 release.
>
> This will probably be the last release of the 2.6.19-stable series, so
> if there are patches that you feel should be applied to that tree,
> please let me know.
There is one here: "Missing critical phys_to_virt in lib/swiotlb.c".
http://lkml.org/lkml/2007/2/4/116
It fixes a DMA related bug which was seen with a variety of drivers
especially on EM64T machines with more than 3GB RAM. I hope you can
extract the patch from this MIME attachment.
Adrian, AFAICS it applies as-is to 2.6.16.y too. I don't have a machine
to test personally, but it is quite obvious.
The mentioned bigger patch has been merged by Linus between 2.6.20 and
2.6.21-rc1.
--
Stefan Richter
-=====-=-=== --=- =-=-=
http://arcgraph.de/sr/
Subject: [PATCH] Missing critical phys_to_virt in lib/swiotlb.c
From: David Moore <[email protected]>
Date: Sun, 04 Feb 2007 13:39:40 -0500
From: David Moore <[email protected]>
Adds missing call to phys_to_virt() in the
lib/swiotlb.c:swiotlb_sync_sg() function. Without this change, a kernel
panic will always occur whenever a SWIOTLB bounce buffer from a
scatter-gather list gets synced.
Signed-off-by: David Moore <[email protected]>
Signed-off-by: Stefan Richter <[email protected]>
---
This is a fraction of patch "[IA64] swiotlb bug fixes" in 2.6.20-git#,
commit cde14bbfb3aa79b479db35bd29e6c083513d8614. Unlike its heading
suggests, it is also important for EM64T.
Example crashes caused by swiotlb_sync_sg:
http://lists.opensuse.org/opensuse-bugs/2006-12/msg02943.html
http://qa.mandriva.com/show_bug.cgi?id=28224
http://www.pchdtv.com/forum/viewtopic.php?t=2063&sid=a959a14a4c2db0eebaab7b0df56103ce
--- linux-2.6.19.x86_64/lib/swiotlb.c.orig 2007-02-04 13:18:41.000000000 -0500
+++ linux-2.6.19.x86_64/lib/swiotlb.c 2007-02-04 13:19:43.000000000 -0500
@@ -750,7 +750,7 @@ swiotlb_sync_sg(struct device *hwdev, st
for (i = 0; i < nelems; i++, sg++)
if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
- sync_single(hwdev, (void *) sg->dma_address,
+ sync_single(hwdev, phys_to_virt(sg->dma_address),
sg->dma_length, dir, target);
}
# HG changeset patch
# User Takashi Iwai <[email protected]>
# Date 1166601341 -3600
# Node ID d53318ba5eb26fbefb63d85c402cb368096436f3
# Parent e20d24388f86121d3ac6f58560e3b7acd686fd39
[ALSA] hda-codec - Don't return error at initialization of modem codec
Some modem codec seem to fail in the initialization, and this
stopped loading of the whole module although the audio is OK.
Since it's usually a non-fatal issue, the driver tries to proceed
to initialize now.
Signed-off-by: Takashi Iwai <[email protected]>
Signed-off-by: Jaroslav Kysela <[email protected]>
committer: Jaroslav Kysela <[email protected]> 1166601341 +0100
--- a/sound/pci/hda/patch_si3054.c Wed Dec 20 08:55:39 2006 +0100
+++ b/sound/pci/hda/patch_si3054.c Wed Dec 20 08:55:41 2006 +0100
@@ -243,7 +243,8 @@ static int si3054_init(struct hda_codec
if((val&SI3054_MEI_READY) != SI3054_MEI_READY) {
snd_printk(KERN_ERR "si3054: cannot initialize. EXT MID = %04x\n", val);
- return -EACCES;
+ /* let's pray that this is no fatal error */
+ /* return -EACCES; */
}
SET_REG(codec, SI3054_GPIO_POLARITY, 0xffff);
Index: linux-2.6.20.noarch/drivers/usb/net/usbnet.c
===================================================================
--- linux-2.6.20.noarch.orig/drivers/usb/net/usbnet.c 2007-02-04 13:44:54.000000000 -0500
+++ linux-2.6.20.noarch/drivers/usb/net/usbnet.c 2007-02-18 18:57:05.000000000 -0500
@@ -1182,6 +1182,9 @@
// NOTE net->name still not usable ...
if (info->bind) {
status = info->bind (dev, udev);
+ if (status < 0)
+ goto out1;
+
// heuristic: "usb%d" for links we know are two-host,
// else "eth%d" when there's reasonable doubt. userspace
// can rename the link if it knows better.
@@ -1208,12 +1211,12 @@
if (status == 0 && dev->status)
status = init_status (dev, udev);
if (status < 0)
- goto out1;
+ goto out3;
if (!dev->rx_urb_size)
dev->rx_urb_size = dev->hard_mtu;
dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
-
+
SET_NETDEV_DEV(net, &udev->dev);
status = register_netdev (net);
if (status)
Greg KH wrote:
> This is the start of the stable review cycle for the 2.6.19.5 release.
>
> This will probably be the last release of the 2.6.19-stable series, so
> if there are patches that you feel should be applied to that tree,
> please let me know.
>
> There are 21 patches in this series, all will be posted as a response to
> this one. If anyone has any issues with these being applied, please let
> us know. If anyone is a maintainer of the proper subsystem, and wants
> to add a Signed-off-by: line to the patch, please respond with it.
>
What is the status of:
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
They fix a serious bug that causes machines to freeze up
or just run very slowly.
I'd like to see these in -stable if possible.
On Wed, 21 Feb 2007 14:31:41 -0500
Chuck Ebbert <[email protected]> wrote:
> Greg KH wrote:
> > This is the start of the stable review cycle for the 2.6.19.5 release.
> >
> > This will probably be the last release of the 2.6.19-stable series, so
> > if there are patches that you feel should be applied to that tree,
> > please let me know.
> >
> > There are 21 patches in this series, all will be posted as a response to
> > this one. If anyone has any issues with these being applied, please let
> > us know. If anyone is a maintainer of the proper subsystem, and wants
> > to add a Signed-off-by: line to the patch, please respond with it.
> >
>
> What is the status of:
>
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
That's mainly an Andi decision. Let's cc him.
> They fix a serious bug that causes machines to freeze up
> or just run very slowly.
>
> I'd like to see these in -stable if possible.
They're not even in mainline yet.
On Wed, 21 Feb 2007, Andrew Morton wrote:
> >
> > http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
> > http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>
> That's mainly an Andi decision. Let's cc him.
Would be good to have Eric also ack them as safe and obvious.
Btw, that latter one has corrupted sign-offs from Andi (it's in the middle
of the text, very confusing).
Linus
Andrew Morton <[email protected]> writes:
> On Wed, 21 Feb 2007 14:31:41 -0500
> Chuck Ebbert <[email protected]> wrote:
>> What is the status of:
>>
>>
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
>>
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>
> That's mainly an Andi decision. Let's cc him.
>
>> They fix a serious bug that causes machines to freeze up
>> or just run very slowly.
>>
>> I'd like to see these in -stable if possible.
>
> They're not even in mainline yet.
If you don't have it you at least want the patch below. It generally
makes the bug non-fatal.
I'm still working my way through possible fixes... Although the
patch in question is close, and normally fixes it in my utmost
paranoia I can still find problems with it.
Eric
commit 2fb12a9bca5ad9aa6dcd2c639b4a7656a8843ef8
Author: Eric W. Biederman <[email protected]>
Date: Tue Feb 13 13:26:25 2007 +0100
[PATCH] x86-64: survive having no irq mapping for a vector
Occasionally the kernel has bugs that result in no irq being found for a
given cpu vector. If we acknowledge the irq the system has a good chance
of continuing even though we dropped an irq message. If we continue to
simply print a message and not acknowledge the irq the system is likely to
become non-responsive shortly there after.
AK: Fixed compilation for UP kernels
Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Cc: "Luigi Genoni" <[email protected]>
Cc: Andi Kleen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Eric W. Biederman wrote:
> Andrew Morton <[email protected]> writes:
>
>> On Wed, 21 Feb 2007 14:31:41 -0500
>> Chuck Ebbert <[email protected]> wrote:
>>> What is the status of:
>>>
>>>
>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>>
>> That's mainly an Andi decision. Let's cc him.
>>
>>> They fix a serious bug that causes machines to freeze up
>>> or just run very slowly.
>>>
>>> I'd like to see these in -stable if possible.
>> They're not even in mainline yet.
>
> If you don't have it you at least want the patch below. It generally
> makes the bug non-fatal.
>
> I'm still working my way through possible fixes... Although the
> patch in question is close, and normally fixes it in my utmost
> paranoia I can still find problems with it.
We've tested it and found no problems so far. It's definitely
better than what's there now. :)
On Wed, Feb 21, 2007 at 02:31:41PM -0500, Chuck Ebbert wrote:
> Greg KH wrote:
> > This is the start of the stable review cycle for the 2.6.19.5 release.
> >
> > This will probably be the last release of the 2.6.19-stable series, so
> > if there are patches that you feel should be applied to that tree,
> > please let me know.
> >
> > There are 21 patches in this series, all will be posted as a response to
> > this one. If anyone has any issues with these being applied, please let
> > us know. If anyone is a maintainer of the proper subsystem, and wants
> > to add a Signed-off-by: line to the patch, please respond with it.
> >
>
> What is the status of:
>
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>
> They fix a serious bug that causes machines to freeze up
> or just run very slowly.
>
> I'd like to see these in -stable if possible.
-stable for 2.6.19 and/or .18?
I haven't pushed out the next round of patches for the 2.6.20-stable
tree, I have a _lot_ of them there to catch up on still...
thanks,
greg k-h
Greg KH wrote:
>> What is the status of:
>>
>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>>
>> They fix a serious bug that causes machines to freeze up
>> or just run very slowly.
>>
>> I'd like to see these in -stable if possible.
>
> -stable for 2.6.19 and/or .18?
>
The bug is new in .19 and is still in .20 and .21-rc.
On Wed, Feb 21, 2007 at 11:47:37AM -0800, Andrew Morton wrote:
> On Wed, 21 Feb 2007 14:31:41 -0500
> Chuck Ebbert <[email protected]> wrote:
>
> > Greg KH wrote:
> > > This is the start of the stable review cycle for the 2.6.19.5 release.
> > >
> > > This will probably be the last release of the 2.6.19-stable series, so
> > > if there are patches that you feel should be applied to that tree,
> > > please let me know.
> > >
> > > There are 21 patches in this series, all will be posted as a response to
> > > this one. If anyone has any issues with these being applied, please let
> > > us know. If anyone is a maintainer of the proper subsystem, and wants
> > > to add a Signed-off-by: line to the patch, please respond with it.
> > >
> >
> > What is the status of:
> >
> > http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
> > http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>
> That's mainly an Andi decision. Let's cc him.
I didn't think the problem was serious enough for a backport. Do we have
user reports?
It's certainly not trivial obvious patches.
Eric, what is your opinion?
-Andi
> commit 2fb12a9bca5ad9aa6dcd2c639b4a7656a8843ef8
> Author: Eric W. Biederman <[email protected]>
> Date: Tue Feb 13 13:26:25 2007 +0100
>
> [PATCH] x86-64: survive having no irq mapping for a vector
Putting that patch into stable would be a good idea, agreed.
-Andi
From: Steve French <[email protected]>
Date: Mon, 22 Jan 2007 01:19:30 +0000 (+0000)
Subject: [CIFS] Fix oops when Windows server sent bad domain name null terminator
X-Git-Tag: v2.6.20^0~147^2
X-Git-Url: http://www2.kernel.org/git/?p=linux%2Fkernel%2Fgit%2Fsfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=8e6f195af0e1f226e9b2e0256af8df46adb9d595
[CIFS] Fix oops when Windows server sent bad domain name null terminator
Fixes RedHat bug 211672
Windows sends one byte (instead of two) of null to terminate final Unicode
string (domain name) in session setup response in some cases - this caused
cifs to misalign some informational strings (making it hard to convert
from UCS16 to UTF8).
Thanks to Shaggy for his help and Akemi Yagi for debugging/testing
Signed-off-by: Shirish Pargaonkar <[email protected]>
Signed-off-by: Steve French <[email protected]>
---
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index bbdda99..7584646 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -182,11 +182,14 @@ static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInf
cFYI(1,("bleft %d",bleft));
- /* word align, if bytes remaining is not even */
- if(bleft % 2) {
- bleft--;
- data++;
- }
+ /* SMB header is unaligned, so cifs servers word align start of
+ Unicode strings */
+ data++;
+ bleft--; /* Windows servers do not always double null terminate
+ their final Unicode string - in which case we
+ now will not attempt to decode the byte of junk
+ which follows it */
+
words_left = bleft / 2;
/* save off server operating system */
Chuck Ebbert wrote:
> Greg KH wrote:
>> This is the start of the stable review cycle for the 2.6.19.5 release.
>>
>> This will probably be the last release of the 2.6.19-stable series, so
>> if there are patches that you feel should be applied to that tree,
>> please let me know.
>
> This patch should go in 2.6.19 and 2.6.20 -stable as well.
> (It's in 2.6.21-rc.)
>
>
>
> ------------------------------------------------------------------------
>
> From: Steve French <[email protected]>
> Date: Mon, 22 Jan 2007 01:19:30 +0000 (+0000)
> Subject: [CIFS] Fix oops when Windows server sent bad domain name null terminator
> X-Git-Tag: v2.6.20^0~147^2
> X-Git-Url: http://www2.kernel.org/git/?p=linux%2Fkernel%2Fgit%2Fsfrench%2Fcifs-2.6.git;a=commitdiff_plain;h=8e6f195af0e1f226e9b2e0256af8df46adb9d595
>
> [CIFS] Fix oops when Windows server sent bad domain name null terminator
Oops, this is already in 2.6.20.
Andi Kleen wrote:
>>> What is the status of:
>>>
>>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
>>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>> That's mainly an Andi decision. Let's cc him.
>
> I didn't think the problem was serious enough for a backport. Do we have
> user reports?
Yes, lots:
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=225399
> It's certainly not trivial obvious patches.
# HG changeset patch
# User Francois Romieu <[email protected]>
# Date 1167168251 18000
# Node ID 7c05514de8881339775cfd86e6357a82735c34f2
# Parent bf34fac7fcce4300f7199337160dab99deefc738
netpoll: drivers must not enable IRQ unconditionally in their NAPI handler
net/core/netpoll.c::netpoll_send_skb() calls the poll handler when
it is available. As netconsole can be used from almost any context,
IRQ must not be enabled blindly in the NAPI handler of a driver which
supports netpoll.
b57bd06655a028aba7b92e1c19c2093e7fcfb341 fixed the issue for the
8139too.c driver.
Signed-off-by: Francois Romieu <[email protected]>
Signed-off-by: Jeff Garzik <[email protected]>
committer: Jeff Garzik <[email protected]> 1167168251 -0500
--- a/drivers/net/8139cp.c Tue Dec 26 15:51:30 2006 -0500
+++ b/drivers/net/8139cp.c Tue Dec 26 16:24:11 2006 -0500
@@ -617,13 +617,15 @@ rx_next:
* this round of polling
*/
if (rx_work) {
+ unsigned long flags;
+
if (cpr16(IntrStatus) & cp_rx_intr_mask)
goto rx_status_loop;
- local_irq_disable();
+ local_irq_save(flags);
cpw16_f(IntrMask, cp_intr_mask);
__netif_rx_complete(dev);
- local_irq_enable();
+ local_irq_restore(flags);
return 0; /* done */
}
--- a/drivers/net/b44.c Tue Dec 26 15:51:30 2006 -0500
+++ b/drivers/net/b44.c Tue Dec 26 16:24:11 2006 -0500
@@ -879,12 +879,14 @@ static int b44_poll(struct net_device *n
}
if (bp->istat & ISTAT_ERRORS) {
- spin_lock_irq(&bp->lock);
+ unsigned long flags;
+
+ spin_lock_irqsave(&bp->lock, flags);
b44_halt(bp);
b44_init_rings(bp);
b44_init_hw(bp, 1);
netif_wake_queue(bp->dev);
- spin_unlock_irq(&bp->lock);
+ spin_unlock_irqrestore(&bp->lock, flags);
done = 1;
}
--- a/drivers/net/forcedeth.c Tue Dec 26 15:51:30 2006 -0500
+++ b/drivers/net/forcedeth.c Tue Dec 26 16:24:11 2006 -0500
@@ -2576,14 +2576,15 @@ static int nv_napi_poll(struct net_devic
int pkts, limit = min(*budget, dev->quota);
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base = get_hwbase(dev);
+ unsigned long flags;
pkts = nv_rx_process(dev, limit);
if (nv_alloc_rx(dev)) {
- spin_lock_irq(&np->lock);
+ spin_lock_irqsave(&np->lock, flags);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
- spin_unlock_irq(&np->lock);
+ spin_unlock_irqrestore(&np->lock, flags);
}
if (pkts < limit) {
@@ -2591,13 +2592,15 @@ static int nv_napi_poll(struct net_devic
netif_rx_complete(dev);
/* re-enable receive interrupts */
- spin_lock_irq(&np->lock);
+ spin_lock_irqsave(&np->lock, flags);
+
np->irqmask |= NVREG_IRQ_RX_ALL;
if (np->msi_flags & NV_MSI_X_ENABLED)
writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
else
writel(np->irqmask, base + NvRegIrqMask);
- spin_unlock_irq(&np->lock);
+
+ spin_unlock_irqrestore(&np->lock, flags);
return 0;
} else {
/* used up our quantum, so reschedule */
--- a/drivers/net/skge.c Tue Dec 26 15:51:30 2006 -0500
+++ b/drivers/net/skge.c Tue Dec 26 16:24:11 2006 -0500
@@ -2920,6 +2920,7 @@ static int skge_poll(struct net_device *
struct skge_hw *hw = skge->hw;
struct skge_ring *ring = &skge->rx_ring;
struct skge_element *e;
+ unsigned long flags;
int to_do = min(dev->quota, *budget);
int work_done = 0;
@@ -2957,12 +2958,12 @@ static int skge_poll(struct net_device *
if (work_done >= to_do)
return 1; /* not done */
- spin_lock_irq(&hw->hw_lock);
+ spin_lock_irqsave(&hw->hw_lock, flags);
__netif_rx_complete(dev);
hw->intr_mask |= irqmask[skge->port];
skge_write32(hw, B0_IMSK, hw->intr_mask);
skge_read32(hw, B0_IMSK);
- spin_unlock_irq(&hw->hw_lock);
+ spin_unlock_irqrestore(&hw->hw_lock, flags);
return 0;
}
Chuck Ebbert <[email protected]> writes:
> We've tested it and found no problems so far. It's definitely
> better than what's there now. :)
Linus Torvalds <[email protected]> writes:
> Would be good to have Eric also ack them as safe and obvious.
Andi Kleen <[email protected]> writes:
> I didn't think the problem was serious enough for a backport. Do we have
> user reports?
>
> It's certainly not trivial obvious patches.
>
> Eric, what is your opinion?
Bug reports:
I have seen a couple of user reports and heard about a few more. Given
that Chuck Ebbert appears to have tested them I'm guessing redhat has
seen a couple of reports as well. One of the issues is that in
some cases you can be susceptible and go for weeks without hitting
this, so the bug reports aren't likely to come back fast. So this is
a long term stability issue.
Even if we just put in my tiny fix that allows us to generally
survive this condition in stable, it prints a nasty warning message
so I expect people will want a more complete fix.
Vulnerability:
I believe it is possible to trigger this bug on any SMP machine.
Obviousness:
The first patch is obvious, but of course that isn't the interesting
bit.
The second patch is still fairly simple, and it appears to have
undergone testing from people besides myself.
So in the interest of a timely if not perfect fix I think it is a
good patch. In particular I do not see any area where it would makes
things worse.
Bugs:
There is one small issue that is probably worth fixing.
apic_in_service_vector only works correctly because we never have
more than one local apic irq in service at the same time, (we keep
irqs disabled during all of the interrupt routines). The appended
incremental patch addresses that.
Outstanding Issues:
The big outstanding issue I am currently working on is that in my
testing I have found evidence to suggest that ioapics do not strictly
follow the pci ordering rules, so exactly when the last interrupt
sent before we masked the interrupt at the interrupt controller will
arrive is in question. So to really be safe we cannot tear down the
data structures for handling the interrupt in the old location until
after we have seen the next interrupt showing up in the new location.
I don't know if it is possible to for the issue I have just described
to cause problems in practice. I intend to fix this for 2.6.21 if the
patch will be accepted. I have a patch that appears to work
that I am currently testing now.
I don't think my more complete fix will be as simple to backport
because it is a more intrusive patch.
Subject: [PATCH] x86_64 irq: Make apic_in_service_vector robust
Currently apic_in_service_vector because it scans isr in the wrong
direction only works reliably because we never enable interrupts
during an interrupt handler. I had the apic priorities backwards
in my head when I wrote it :(
It turns out that we have already saved off the vector we are servicing
in the irq regs so use that instead to make the code simpler and
more robust.
Signed-off-by: Eric W. Biederman <[email protected]>
---
arch/x86_64/kernel/io_apic.c | 10 ++--------
1 files changed, 2 insertions(+), 8 deletions(-)
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index fc42340..b6f9896 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1395,15 +1395,9 @@ static int ioapic_retrigger_irq(unsigned int irq)
static unsigned apic_in_service_vector(void)
{
- unsigned isr, vector;
+ unsigned vector;
/* Figure out which vector we are servicing */
- for (vector = FIRST_EXTERNAL_VECTOR; vector < FIRST_SYSTEM_VECTOR; vector += 32) {
- isr = apic_read(APIC_ISR + ((vector/32) * 0x10));
- if (isr)
- break;
- }
- /* Find the low bits of the vector we are servicing */
- vector += __ffs(isr);
+ vector = ~get_irq_regs()->orig_rax;
return vector;
}
--
1.5.0.g53756
On Wed, Feb 21, 2007 at 05:39:01PM -0500, Chuck Ebbert wrote:
> Andi Kleen wrote:
> >>> What is the status of:
> >>>
> >>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
> >>> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
> >> That's mainly an Andi decision. Let's cc him.
> >
> > I didn't think the problem was serious enough for a backport. Do we have
> > user reports?
>
> Yes, lots:
>
> https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=225399
Ok for me then.
-Andi
Greg KH wrote:
> -stable review patch. If anyone has any objections, please let us know.
>
> ------------------
> Suspending with the cx88xx module loaded causes the system to lock up
> because the cx88_audio_thread kthread was missing a try_to_freeze()
> call, which caused it to go into a tight loop and result in softlockup
> when suspending. Fix that.
>
> (cherry picked from commit a96afb3e9428f2e7463344f12dbc85faf08e2e09)
>
> Signed-off-by: Robert Hancock <[email protected]>
> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
> Signed-off-by: Michael Krufky <[email protected]>
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>
> ---
> drivers/media/video/cx88/cx88-tvaudio.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> --- linux-2.6.19.4.orig/drivers/media/video/cx88/cx88-tvaudio.c
> +++ linux-2.6.19.4/drivers/media/video/cx88/cx88-tvaudio.c
> @@ -38,6 +38,7 @@
> #include <linux/module.h>
> #include <linux/moduleparam.h>
> #include <linux/errno.h>
> +#include <linux/freezer.h>
> #include <linux/kernel.h>
> #include <linux/slab.h>
> #include <linux/mm.h>
> @@ -974,6 +975,7 @@ int cx88_audio_thread(void *data)
> msleep_interruptible(1000);
> if (kthread_should_stop())
> break;
> + try_to_freeze();
>
> /* just monitor the audio status for now ... */
> memset(&t, 0, sizeof(t));
>
drivers/media/video/cx88/cx88-tvaudio.c:41:27: error: linux/freezer.h: No such file or directory
make[4]: *** [drivers/media/video/cx88/cx88-tvaudio.o] Error 1
make[3]: *** [drivers/media/video/cx88] Error 2
make[3]: *** Waiting for unfinished jobs....
Chuck Ebbert wrote:
> Greg KH wrote:
>> -stable review patch. If anyone has any objections, please let us know.
>>
>> ------------------
>> Suspending with the cx88xx module loaded causes the system to lock up
>> because the cx88_audio_thread kthread was missing a try_to_freeze()
>> call, which caused it to go into a tight loop and result in softlockup
>> when suspending. Fix that.
>>
>> (cherry picked from commit a96afb3e9428f2e7463344f12dbc85faf08e2e09)
>>
>> Signed-off-by: Robert Hancock <[email protected]>
>> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
>> Signed-off-by: Michael Krufky <[email protected]>
>> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>>
>> ---
>> drivers/media/video/cx88/cx88-tvaudio.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> --- linux-2.6.19.4.orig/drivers/media/video/cx88/cx88-tvaudio.c
>> +++ linux-2.6.19.4/drivers/media/video/cx88/cx88-tvaudio.c
>> @@ -38,6 +38,7 @@
>> #include <linux/module.h>
>> #include <linux/moduleparam.h>
>> #include <linux/errno.h>
>> +#include <linux/freezer.h>
>> #include <linux/kernel.h>
>> #include <linux/slab.h>
>> #include <linux/mm.h>
>> @@ -974,6 +975,7 @@ int cx88_audio_thread(void *data)
>> msleep_interruptible(1000);
>> if (kthread_should_stop())
>> break;
>> + try_to_freeze();
>>
>> /* just monitor the audio status for now ... */
>> memset(&t, 0, sizeof(t));
>>
>
> drivers/media/video/cx88/cx88-tvaudio.c:41:27: error: linux/freezer.h: No such file or directory
> make[4]: *** [drivers/media/video/cx88/cx88-tvaudio.o] Error 1
> make[3]: *** [drivers/media/video/cx88] Error 2
> make[3]: *** Waiting for unfinished jobs....
>
Yikes... This one shouldn't have been sent to 2.6.18.y nor 2.6.19.y ... tree-mixup :-/
Please drop this one. Thanks, Chuck.
Sorry about that...
-Mike Krufky
# HG changeset patch
# User Eric Sandeen <[email protected]>
# Date 1168070123 28800
# Node ID 2ce8209bd3b1a96b6701821b70144b69d61098c6
# Parent e1242b48d243513737eaa39f3ad0a7d849030359
[PATCH] fix memory corruption from misinterpreted bad_inode_ops return values
CVE-2006-5753 is for a case where an inode can be marked bad, switching
the ops to bad_inode_ops, which are all connected as:
static int return_EIO(void)
{
return -EIO;
}
#define EIO_ERROR ((void *) (return_EIO))
static struct inode_operations bad_inode_ops =
{
.create = bad_inode_create
...etc...
The problem here is that the void cast causes return types to not be
promoted, and for ops such as listxattr which expect more than 32 bits of
return value, the 32-bit -EIO is interpreted as a large positive 64-bit
number, i.e. 0x00000000fffffffa instead of 0xfffffffa.
This goes particularly badly when the return value is taken as a number of
bytes to copy into, say, a user's buffer for example...
I originally had coded up the fix by creating a return_EIO_<TYPE> macro
for each return type, like this:
static int return_EIO_int(void)
{
return -EIO;
}
#define EIO_ERROR_INT ((void *) (return_EIO_int))
static struct inode_operations bad_inode_ops =
{
.create = EIO_ERROR_INT,
...etc...
but Al felt that it was probably better to create an EIO-returner for each
actual op signature. Since so few ops share a signature, I just went ahead
& created an EIO function for each individual file & inode op that returns
a value.
Signed-off-by: Eric Sandeen <[email protected]>
Cc: Al Viro <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
committer: Linus Torvalds <[email protected]> 1168070123 -0800
--- a/fs/bad_inode.c Fri Jan 05 23:55:23 2007 -0800
+++ b/fs/bad_inode.c Fri Jan 05 23:55:23 2007 -0800
@@ -14,59 +14,307 @@
#include <linux/time.h>
#include <linux/smp_lock.h>
#include <linux/namei.h>
-
-static int return_EIO(void)
-{
- return -EIO;
-}
-
-#define EIO_ERROR ((void *) (return_EIO))
+#include <linux/poll.h>
+
+
+static loff_t bad_file_llseek(struct file *file, loff_t offset, int origin)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_read(struct file *filp, char __user *buf,
+ size_t size, loff_t *ppos)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_write(struct file *filp, const char __user *buf,
+ size_t siz, loff_t *ppos)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ return -EIO;
+}
+
+static int bad_file_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ return -EIO;
+}
+
+static unsigned int bad_file_poll(struct file *filp, poll_table *wait)
+{
+ return POLLERR;
+}
+
+static int bad_file_ioctl (struct inode *inode, struct file *filp,
+ unsigned int cmd, unsigned long arg)
+{
+ return -EIO;
+}
+
+static long bad_file_unlocked_ioctl(struct file *file, unsigned cmd,
+ unsigned long arg)
+{
+ return -EIO;
+}
+
+static long bad_file_compat_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ return -EIO;
+}
+
+static int bad_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ return -EIO;
+}
+
+static int bad_file_open(struct inode *inode, struct file *filp)
+{
+ return -EIO;
+}
+
+static int bad_file_flush(struct file *file, fl_owner_t id)
+{
+ return -EIO;
+}
+
+static int bad_file_release(struct inode *inode, struct file *filp)
+{
+ return -EIO;
+}
+
+static int bad_file_fsync(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ return -EIO;
+}
+
+static int bad_file_aio_fsync(struct kiocb *iocb, int datasync)
+{
+ return -EIO;
+}
+
+static int bad_file_fasync(int fd, struct file *filp, int on)
+{
+ return -EIO;
+}
+
+static int bad_file_lock(struct file *file, int cmd, struct file_lock *fl)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_sendfile(struct file *in_file, loff_t *ppos,
+ size_t count, read_actor_t actor, void *target)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_sendpage(struct file *file, struct page *page,
+ int off, size_t len, loff_t *pos, int more)
+{
+ return -EIO;
+}
+
+static unsigned long bad_file_get_unmapped_area(struct file *file,
+ unsigned long addr, unsigned long len,
+ unsigned long pgoff, unsigned long flags)
+{
+ return -EIO;
+}
+
+static int bad_file_check_flags(int flags)
+{
+ return -EIO;
+}
+
+static int bad_file_dir_notify(struct file *file, unsigned long arg)
+{
+ return -EIO;
+}
+
+static int bad_file_flock(struct file *filp, int cmd, struct file_lock *fl)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_splice_write(struct pipe_inode_info *pipe,
+ struct file *out, loff_t *ppos, size_t len,
+ unsigned int flags)
+{
+ return -EIO;
+}
+
+static ssize_t bad_file_splice_read(struct file *in, loff_t *ppos,
+ struct pipe_inode_info *pipe, size_t len,
+ unsigned int flags)
+{
+ return -EIO;
+}
static const struct file_operations bad_file_ops =
{
- .llseek = EIO_ERROR,
- .aio_read = EIO_ERROR,
- .read = EIO_ERROR,
- .write = EIO_ERROR,
- .aio_write = EIO_ERROR,
- .readdir = EIO_ERROR,
- .poll = EIO_ERROR,
- .ioctl = EIO_ERROR,
- .mmap = EIO_ERROR,
- .open = EIO_ERROR,
- .flush = EIO_ERROR,
- .release = EIO_ERROR,
- .fsync = EIO_ERROR,
- .aio_fsync = EIO_ERROR,
- .fasync = EIO_ERROR,
- .lock = EIO_ERROR,
- .sendfile = EIO_ERROR,
- .sendpage = EIO_ERROR,
- .get_unmapped_area = EIO_ERROR,
+ .llseek = bad_file_llseek,
+ .read = bad_file_read,
+ .write = bad_file_write,
+ .aio_read = bad_file_aio_read,
+ .aio_write = bad_file_aio_write,
+ .readdir = bad_file_readdir,
+ .poll = bad_file_poll,
+ .ioctl = bad_file_ioctl,
+ .unlocked_ioctl = bad_file_unlocked_ioctl,
+ .compat_ioctl = bad_file_compat_ioctl,
+ .mmap = bad_file_mmap,
+ .open = bad_file_open,
+ .flush = bad_file_flush,
+ .release = bad_file_release,
+ .fsync = bad_file_fsync,
+ .aio_fsync = bad_file_aio_fsync,
+ .fasync = bad_file_fasync,
+ .lock = bad_file_lock,
+ .sendfile = bad_file_sendfile,
+ .sendpage = bad_file_sendpage,
+ .get_unmapped_area = bad_file_get_unmapped_area,
+ .check_flags = bad_file_check_flags,
+ .dir_notify = bad_file_dir_notify,
+ .flock = bad_file_flock,
+ .splice_write = bad_file_splice_write,
+ .splice_read = bad_file_splice_read,
};
+static int bad_inode_create (struct inode *dir, struct dentry *dentry,
+ int mode, struct nameidata *nd)
+{
+ return -EIO;
+}
+
+static struct dentry *bad_inode_lookup(struct inode *dir,
+ struct dentry *dentry, struct nameidata *nd)
+{
+ return ERR_PTR(-EIO);
+}
+
+static int bad_inode_link (struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ return -EIO;
+}
+
+static int bad_inode_unlink(struct inode *dir, struct dentry *dentry)
+{
+ return -EIO;
+}
+
+static int bad_inode_symlink (struct inode *dir, struct dentry *dentry,
+ const char *symname)
+{
+ return -EIO;
+}
+
+static int bad_inode_mkdir(struct inode *dir, struct dentry *dentry,
+ int mode)
+{
+ return -EIO;
+}
+
+static int bad_inode_rmdir (struct inode *dir, struct dentry *dentry)
+{
+ return -EIO;
+}
+
+static int bad_inode_mknod (struct inode *dir, struct dentry *dentry,
+ int mode, dev_t rdev)
+{
+ return -EIO;
+}
+
+static int bad_inode_rename (struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ return -EIO;
+}
+
+static int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
+ int buflen)
+{
+ return -EIO;
+}
+
+static int bad_inode_permission(struct inode *inode, int mask,
+ struct nameidata *nd)
+{
+ return -EIO;
+}
+
+static int bad_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ return -EIO;
+}
+
+static int bad_inode_setattr(struct dentry *direntry, struct iattr *attrs)
+{
+ return -EIO;
+}
+
+static int bad_inode_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ return -EIO;
+}
+
+static ssize_t bad_inode_getxattr(struct dentry *dentry, const char *name,
+ void *buffer, size_t size)
+{
+ return -EIO;
+}
+
+static ssize_t bad_inode_listxattr(struct dentry *dentry, char *buffer,
+ size_t buffer_size)
+{
+ return -EIO;
+}
+
+static int bad_inode_removexattr(struct dentry *dentry, const char *name)
+{
+ return -EIO;
+}
+
static struct inode_operations bad_inode_ops =
{
- .create = EIO_ERROR,
- .lookup = EIO_ERROR,
- .link = EIO_ERROR,
- .unlink = EIO_ERROR,
- .symlink = EIO_ERROR,
- .mkdir = EIO_ERROR,
- .rmdir = EIO_ERROR,
- .mknod = EIO_ERROR,
- .rename = EIO_ERROR,
- .readlink = EIO_ERROR,
+ .create = bad_inode_create,
+ .lookup = bad_inode_lookup,
+ .link = bad_inode_link,
+ .unlink = bad_inode_unlink,
+ .symlink = bad_inode_symlink,
+ .mkdir = bad_inode_mkdir,
+ .rmdir = bad_inode_rmdir,
+ .mknod = bad_inode_mknod,
+ .rename = bad_inode_rename,
+ .readlink = bad_inode_readlink,
/* follow_link must be no-op, otherwise unmounting this inode
won't work */
- .truncate = EIO_ERROR,
- .permission = EIO_ERROR,
- .getattr = EIO_ERROR,
- .setattr = EIO_ERROR,
- .setxattr = EIO_ERROR,
- .getxattr = EIO_ERROR,
- .listxattr = EIO_ERROR,
- .removexattr = EIO_ERROR,
+ /* put_link returns void */
+ /* truncate returns void */
+ .permission = bad_inode_permission,
+ .getattr = bad_inode_getattr,
+ .setattr = bad_inode_setattr,
+ .setxattr = bad_inode_setxattr,
+ .getxattr = bad_inode_getxattr,
+ .listxattr = bad_inode_listxattr,
+ .removexattr = bad_inode_removexattr,
+ /* truncate_range returns void */
};
@@ -88,7 +336,7 @@ static struct inode_operations bad_inode
* on it to fail from this point on.
*/
-void make_bad_inode(struct inode * inode)
+void make_bad_inode(struct inode *inode)
{
remove_inode_hash(inode);
@@ -113,7 +361,7 @@ EXPORT_SYMBOL(make_bad_inode);
* Returns true if the inode in question has been marked as bad.
*/
-int is_bad_inode(struct inode * inode)
+int is_bad_inode(struct inode *inode)
{
return (inode->i_op == &bad_inode_ops);
}
Hmm.. I seem to have failed to send out this reply a few days ago :(
Linus Torvalds <[email protected]> writes:
> On Wed, 21 Feb 2007, Andrew Morton wrote:
>> >
>> >
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-simplfy-__assign_irq_vector.patch
>> >
> http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
>>
>> That's mainly an Andi decision. Let's cc him.
>
> Would be good to have Eric also ack them as safe and obvious.
>
> Btw, that latter one has corrupted sign-offs from Andi (it's in the middle
> of the text, very confusing).
There are two questions.
1) What can we do to make the situation better.
2) Is the hole completely plugged.
When I wrote the patch I had the local apic priorities backwards in my
head. So apic_in_service_vector can return the wrong value if two
irqs are in service. Now I don't think we allows ourselves to enable
interrupts in an interrupt service routing until after we have acked
the local apic so this should be harmless. The fix is also trivial
of just having apic_in_service_vector return: "~get_irq_regs()->orig_rax".
Except for that one possible problem everything I can think of are
just theoretical cracks at this point, and they don't make the
situation any worse.
Given that this patch has appears to have undergone a noticeable
amount of testing, by people other than myself, and clears up the
symptoms. I have no problem
Eric
On Tue, 27 Feb 2007, Eric W. Biederman wrote:
> > http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.20/2.6.20-mm2/broken-out/x86_64-mm-handle-irqs-pending-in-irr-during-irq-migration.patch
> >>
> >> That's mainly an Andi decision. Let's cc him.
> >
> > Would be good to have Eric also ack them as safe and obvious.
> >
> > Btw, that latter one has corrupted sign-offs from Andi (it's in the middle
> > of the text, very confusing).
>
> There are two questions.
> 1) What can we do to make the situation better.
> 2) Is the hole completely plugged.
>
> When I wrote the patch I had the local apic priorities backwards in my
> head. So apic_in_service_vector can return the wrong value if two
> irqs are in service. Now I don't think we allows ourselves to enable
> interrupts in an interrupt service routing until after we have acked
> the local apic so this should be harmless. The fix is also trivial
> of just having apic_in_service_vector return: "~get_irq_regs()->orig_rax".
>
> Except for that one possible problem everything I can think of are
> just theoretical cracks at this point, and they don't make the
> situation any worse.
>
> Given that this patch has appears to have undergone a noticeable
> amount of testing, by people other than myself, and clears up the
> symptoms. I have no problem
Hi Eric,
Thanks for getting this cruft cleaned up. I have a few comments
regarding;
handle-irqs-pending-in-irr-during-irq-migration.patch
1) It relies on checking the IRR, this could race with the corresponding
vector bit being set by hardware.
2) apic_handle_pending_vector is oddly named since it doesn't actually
handle a pending vector but drops it if it has been freed.
3) It looks complex
So how about the following scheme. Add a check in do_IRQ whether the irq's
domain contains the current cpu, if not we free the vector upon handler
completion.
Cheers,
Zwane
Zwane Mwaikambo <[email protected]> writes:
> Hi Eric,
> Thanks for getting this cruft cleaned up. I have a few comments
> regarding;
>
> handle-irqs-pending-in-irr-during-irq-migration.patch
>
> 1) It relies on checking the IRR, this could race with the corresponding
> vector bit being set by hardware.
The mostly correct assumption is that because that vector is masked and
has been for a while we should not have a race.
> 2) apic_handle_pending_vector is oddly named since it doesn't actually
> handle a pending vector but drops it if it has been freed.
>
> 3) It looks complex
>
> So how about the following scheme. Add a check in do_IRQ whether the irq's
> domain contains the current cpu, if not we free the vector upon handler
> completion.
Because that check will leak vector entries. And after a while the
box will be unable to migrate irqs, and possible something more
severe.
Yes. It is moderately complex. After receiving a little feedback
like this I have something much simpler and more robust mered into the
current git for 2.6.21. Which except for my stupid it doesn't compile
on uniprocessor bug should be good.
However it took me 13 patches to come up with something clean and
simple.
Basically I wait until an irq has arrived at the new location until I
free it, and even then I send a lowest priority IPI to land to the cpu in
question before I free it so that if that other cpu has it stuck in the
pending bit that gets processed before the freeing happens.
Even with that I'm still only 99% certain that the last in flight irq before
we reprogrammed it actually made it to a different cpus local apic. But
there appears to be nothing more that I can do. I have exhausted every
property I can find. Added to that is the fact that simply handing the
irq in IRR empirically is sufficient. So I truly believe in practice
the code in my first patch is sufficient, and what I am doing for 2.6.21
is better simply because it is simpler and much more paranoid and thus
affords us with a bit of margin. If one irq is delivered to a local
apic you would expect the previous incarnation of that irq to be
delivered to a local apic first...
Honestly I would be completely happy if all that gets back ported is
my stupid patch, that adds:
if (!disable_apic)
ack_APIC_irq();
Before
if (printk_ratelimit())
printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
In do_IRQ. That is sufficient in most cases to keep the box from
falling over. Is obviously correct. And only emits a scary message.
If that isn't sufficient to give everyone warm fuzzy. I think the
patch under discussion make sense for a backport. At least it doesn't
change lot so things.
Honestly. I am happy if I fix this for 2.6.21. Beyond that I am
happy to offer my advice but I have no expectations of anyone
following it. Possibly I suffer from giving to complete an answer?
What are the rules that are supposed to govern backports to stable
trees these days anyway?
Eric
On Wed, Feb 28, 2007 at 05:28:27AM -0700, Eric W. Biederman wrote:
>
> What are the rules that are supposed to govern backports to stable
> trees these days anyway?
Documentation/stable_kernel_rules.txt
thanks,
greg k-h
Greg KH <[email protected]> writes:
> On Wed, Feb 28, 2007 at 05:28:27AM -0700, Eric W. Biederman wrote:
>>
>> What are the rules that are supposed to govern backports to stable
>> trees these days anyway?
>
> Documentation/stable_kernel_rules.txt
Ok if that is really what we are going with, the this silly patch isn't
simple enough for a backport. There used to other rules to the effect
the patch must be merged in mainline, and we only backport to one kernel
revision.
I think it fails the 100 lines with context test.
The meaning of obviously correct is a little bit nebulous. But if
something is obvious multiple people can easily understand what
is going on. I haven't gotten any feedback that has said yes I
see what you are doing on the mentioned patch.
I'm really not certain how this patch got seriously proposed then.
I guess it was the serious of the issues of peoples boxes falling
over.
I guess somewhere I got the rules for weird vendor trees confused with
our stable branches. The relaxed stable branch rules probably did it
to me.
So the best we can do is the commit below for a backport. It doesn't
fix the issue but it generally keeps the machines from falling over.
p.s. The copy below is whitespace damaged because I just cut and
pasted it into this email.
commit 2fb12a9bca5ad9aa6dcd2c639b4a7656a8843ef8
Author: Eric W. Biederman <[email protected]>
Date: Tue Feb 13 13:26:25 2007 +0100
[PATCH] x86-64: survive having no irq mapping for a vector
Occasionally the kernel has bugs that result in no irq being found for a
given cpu vector. If we acknowledge the irq the system has a good chance
of continuing even though we dropped an irq message. If we continue to
simply print a message and not acknowledge the irq the system is likely to
become non-responsive shortly there after.
AK: Fixed compilation for UP kernels
Signed-off-by: Eric W. Biederman <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Cc: "Luigi Genoni" <[email protected]>
Cc: Andi Kleen <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
diff --git a/arch/x86_64/kernel/irq.c b/arch/x86_64/kernel/irq.c
index 0c06af6..3bc30d2 100644
--- a/arch/x86_64/kernel/irq.c
+++ b/arch/x86_64/kernel/irq.c
@@ -18,6 +18,7 @@
#include <asm/uaccess.h>
#include <asm/io_apic.h>
#include <asm/idle.h>
+#include <asm/smp.h>
atomic_t irq_err_count;
@@ -120,9 +121,14 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
if (likely(irq < NR_IRQS))
generic_handle_irq(irq);
- else if (printk_ratelimit())
- printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
- __func__, smp_processor_id(), vector);
+ else {
+ if (!disable_apic)
+ ack_APIC_irq();
+
+ if (printk_ratelimit())
+ printk(KERN_EMERG "%s: %d.%d No irq handler for vector\n",
+ __func__, smp_processor_id(), vector);
+ }
irq_exit();