-stable review
Subsystems (11)
cover -stable review
This is the start of the stable review cycle for the 2.6.11.11 release. There are 16 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a
signed-off-by: line to the patch, please respond with it.
These patches are sent out with a number of different people on the Cc: line. If you wish to be a reviewer, please email [email protected] to add your name to the list. If you want to be off the reviewer list, also email us.
Responses should be made by Wed, May 25, 23:00 UTC. Anything received after that time, might be too late.
thanks,
the -stable release team (i.e. the ones wearing the joker hat in the corner...)
PATCH 1/16 Fix get_unmapped_area sanity tests
Fix get_unmapped_area sanity tests
As noted by Chris Wright, we need to do the full range of tests regardless of whether MAP_FIXED is set or not, so re-organize get_unmapped_area() slightly to do the sanity checks unconditionally.
--- include/linux/err.h | 4 ++- mm/mmap.c | 59 +++++++++++++++++++++++++++------------------------- 2 files changed, 34 insertions(+), 29 deletions(-)
include/linux/err.h +3 -1
@@ -13,6 +13,8 @@* This should be a per-architecture thing, to allow different * error and pointer decisions. */ +#define IS_ERR_VALUE (x) unlikely((x) > (unsigned long)-1000L) +static inline void *ERR_PTR (long error) {return (void *) error;
@@ -25,7 +27,7 @@static inline long IS_ERR (const void *ptr) { -return unlikely ((unsigned long )ptr > (unsigned long )-1000L ); +return IS_ERR_VALUE ((unsigned long )ptr); }#endif /* _LINUX_ERR_H */
mm/mmap.c +31 -28
68 lines not on this page · raw message
PATCH 2/16 3c59x: only put the device into D3 when we're actually using WOL
In reply to Chris WrightDuring a warm boot the device is in D3 and has troubles coming out of it.
--- drivers/net/3c59x.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)
drivers/net/3c59x.c +6 -3
@@ -1581,7 +1581,8 @@if (VORTEX_PCI (vp)) {pci_set_power_state (VORTEX_PCI (vp),PCI_D0 );/* Go active */ -pci_restore_state (VORTEX_PCI (vp)); +if (vp->pm_state_valid) +pci_restore_state (VORTEX_PCI (vp));pci_enable_device (VORTEX_PCI (vp)); }
@@ -2741,6 +2742,7 @@outl (0 , ioaddr + DownListPtr);if (final_down &&VORTEX_PCI (vp)) { + vp->pm_state_valid =1 ;pci_save_state (VORTEX_PCI (vp));acpi_set_WOL (dev); }
@@ -3243,9 +3245,10 @@outw (RxEnable, ioaddr +EL3_CMD );pci_enable_wake (VORTEX_PCI (vp),0 ,1 ); + +/* Change the power state to D3; RxEnable doesn't take effect. */ +pci_set_power_state (VORTEX_PCI (vp), PCI_D3hot); } -/* Change the power state to D3; RxEnable doesn't take effect. */ -pci_set_power_state (VORTEX_PCI (vp), PCI_D3hot); }
Re: [patch 02/16] 3c59x: only put the device into D3 when we're actually using WOL
adding what i missed in the first place :)
Quoted 41 lines · Chris Wright
During a warm boot the device is in D3 and has troubles coming out of it.
Signed-off-by Andrew Morton <[email protected]>Signed-off-by Linus Torvalds <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/net/3c59x.c | 9 ++++++--- 1 files changed, 6 insertions(+), 3 deletions(-)---
linux-2.6.11.10.orig/drivers/net/3c59x.c2005-05-20 09:34:18.788560304
-0700 +++linux-2.6.11.10/drivers/net/3c59x.c2005-05-20 09:34:22.644974040
-0700 @@ -1581,7 +1581,8 @@drivers/net/3c59x.c +6
-3if (VORTEX_PCI (vp)) {pci_set_power_state (VORTEX_PCI (vp),PCI_D0 );/* Go active */ -pci_restore_state (VORTEX_PCI (vp)); +if (vp->pm_state_valid) +pci_restore_state (VORTEX_PCI (vp));pci_enable_device (VORTEX_PCI (vp)); }@@ -2741,6 +2742,7 @@outl (0 , ioaddr + DownListPtr);if (final_down &&VORTEX_PCI (vp)) { + vp->pm_state_valid =1 ;pci_save_state (VORTEX_PCI (vp));acpi_set_WOL (dev); }@@ -3243,9 +3245,10 @@outw (RxEnable, ioaddr +EL3_CMD );pci_enable_wake (VORTEX_PCI (vp),0 ,1 ); + +/* Change the power state to D3; RxEnable doesn't take effect. */ +pci_set_power_state (VORTEX_PCI (vp), PCI_D3hot); } -/* Change the power state to D3; RxEnable doesn't take effect. */ -pci_set_power_state (VORTEX_PCI (vp), PCI_D3hot); }
PATCH 3/16 : Fix smp race.
In reply to Chris WrightThe patch below fixes an smp race that happens on such systems under heavy load.
This bug was reported and solved by Steve Herrell <[email protected]>
--- net/bridge/netfilter/ebtables.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-)
net/bridge/netfilter/ebtables.c +2 -1
@@ -179,9 +179,10 @@struct ebt_chainstack *cs;struct ebt_entries *chaininfo;char *base; -struct ebt_table_info *private = table->private; +struct ebt_table_info *private;read_lock_bh (&table->lock); + private = table->private; cb_base =COUNTER_BASE (private->counters, private->nentries,smp_processor_id ());if (private->chainstack)
PATCH 4/16 ext3: fix race between ext3 make block reservation and reservation window discard
In reply to Chris WrightThis patch fixed a race between ext3_discard_reservation() and ext3_try_to_allocate_with_rsv().
There is a window where ext3_discard_reservation will remove an already unlinked reservation window node from the filesystem reservation tree:
It thinks the reservation is still linked in the filesystem reservation tree, but it is actually temperately removed from the tree by allocate_new_reservation() when it failed to make a new reservation from the current group and try to make a new reservation from next block group.
Here is how it could happen:
CPU 1
try to allocate a block in group1 with given reservation window my_rsv ext3_try_to_allocate_with_rsv(group
----copy reservation window my_rsv into local rsv_copy ext3_try_to_allocate(...rsv_copy)
----no free block in existing reservation window, ----need a new reservation window
spin_lock(&rsv_lock);
CPU 2
ext3_discard_reservation
if (!rsv_is_empty()
----this is true
spin_lock(&rsv_lock)
----waiting for thread 1
CPU 1:
allocate_new_reservation
failed to reserve blocks in this group remove the window from the tree rsv_window_remove(my_rsv)
----window node is unlinked from the tree here
return -1
spin_unlock(&rsv_lock)ext3_try_to_allocate_with_rsv() failed in this group group++
CPU 2
spin_lock(&rsv_lock) succeed rsv_remove_window () ---------------break, trying to remove a unlinked node from the tree ....
CPU 1:ext3_try_to_allocate_with_rsv(group, my_rsv)
rsv_is_empty is true, need a new reservation window spin_lock(&rsv_lock); ^--------------- spinning forever
We need to re-check whether the reservation window is still linked to the tree after grab the rsv_lock spin lock in ext3_discard_reservation, to prevent panic in rsv_remove_window->rb_erase.
--- fs/ext3/balloc.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-)
fs/ext3/balloc.c +2 -1
@@ -268,7 +268,8 @@if (!rsv_is_empty (&rsv->rsv_window)) {spin_lock (rsv_lock); -rsv_window_remove (inode->i_sb, rsv); +if (!rsv_is_empty (&rsv->rsv_window)) +rsv_window_remove (inode->i_sb, rsv);spin_unlock (rsv_lock); } }
Re: [patch 04/16] ext3: fix race between ext3 make block reservation and reservation window discard
Hi,
Does this patch fix the "Assertion failure in log_do_checkpoint" for witch Jan Kara submitted a workaround to the list earlier?
http://lkml.org/lkml/2005/5/6/30
Thanks in advance,
Rodrigo Wanderley
Re: [patch 04/16] ext3: fix race between ext3 make block reservation and reservation window discard
Quoted 8 lines · Rodrigo Steinmüller Wanderley
Hi,
Does this patch fix the "Assertion failure inlog_do_checkpoint" for witch Jan Kara submitted a workaround to the list earlier?http://lkml.org/lkml/2005/5/6/30
Thanks in advance,
Rodrigo Wanderley
This patch really is to prevent re-remove an already removed reservation window node from the filesystem red-black reservation tree. It has nothing to do with the log_do_checkpoint failure.
Mingming
PATCH 5/16 PPC64: Fix LPAR IOMMU setup code for p630
In reply to Chris WrightHere's a fix to deal with p630 systems in LPAR mode. They're to date the only system that in some cases might lack a dma-window property for the bus, but contain an overriding property in the device node for the specific adapter/slot. This makes the device setup code a bit more complex since it needs to do some of the things that the bus setup code has already done.
--- arch/ppc64/kernel/pSeries_iommu.c | 55 +++++++++++++++++++++++++++++++++++++- 1 files changed, 54 insertions(+), 1 deletion(-)
arch/ppc64/kernel/pSeries_iommu.c +54 -1
@@ -401,6 +401,8 @@struct device_node *dn, *pdn;unsigned int *dma_window =NULL ; +DBG ("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n" , bus, bus->self); + dn =pci_bus_to_OF_node (bus);/* Find nearest ibm,dma-window, walking up the device tree */
@@ -455,6 +457,56 @@ } } +static void iommu_dev_setup_pSeriesLP (struct pci_dev *dev) +{ +struct device_node *pdn, *dn; +struct iommu_table *tbl; +int *dma_window =NULL ; + +DBG ("iommu_dev_setup_pSeriesLP, dev %p (%s)\n" , dev, dev->pretty_name); + +/* dev setup for LPAR is a little tricky, since the device tree might +* contain the dma-window properties per-device and not neccesarily +* for the bus. So we need to search upwards in the tree until we +* either hit a dma-window property, OR find a parent with a table +* already allocated. +*/ + dn =pci_device_to_OF_node (dev); + +for (pdn = dn; pdn && !pdn->iommu_table; pdn = pdn->parent) { + dma_window = (unsigned int *)get_property (pdn,"ibm,dma-window" ,NULL ); +if (dma_window) +break ; + } + +/* Check for parent == NULL so we don't try to setup the empty EADS +* slots on POWER4 machines. +*/ +if (dma_window ==NULL || pdn->parent ==NULL ) { +/* Fall back to regular (non-LPAR) dev setup */ +DBG ("No dma window for device, falling back to regular setup\n" ); +iommu_dev_setup_pSeries (dev); +return ; + }else { +DBG ("Found DMA window, allocating table\n" ); + } + +if (!pdn->iommu_table) { +/* iommu_table_setparms_lpar needs bussubno. */ + pdn->bussubno = pdn->phb->bus->number; + + tbl = (struct iommu_table *)kmalloc (sizeof (struct iommu_table ), +GFP_KERNEL ); + +iommu_table_setparms_lpar (pdn->phb, pdn, tbl, dma_window); + + pdn->iommu_table =iommu_init_table (tbl); + } + +if (pdn != dn) + dn->iommu_table = pdn->iommu_table; +} +static void iommu_bus_setup_null (struct pci_bus *b) { }static void iommu_dev_setup_null (struct pci_dev *d) { }
@@ -479,13 +531,14 @@ ppc_md.tce_free = tce_free_pSeriesLP; } ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; + ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; }else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; + ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; } - ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries;pci_iommu_init (); }
PATCH 6/16 Fix matroxfb on big-endian hardware
In reply to Chris WrightThere was too much/too few byteswapping done by driver and hardware in matroxfb on big endian hardware. Change fixes mirrored/split/corrupted letters seen on screen when using accelerated matroxfb mode.
Patch was tested on Mips (by Peter) and x86-64 (by Petr).
--- drivers/video/matrox/matroxfb_accel.c | 14 +++++++++++--- drivers/video/matrox/matroxfb_base.h | 4 ++-- 2 files changed, 13 insertions(+), 5 deletions(-)
drivers/video/matrox/matroxfb_accel.c +11 -3
@@ -438,13 +438,21 @@ }else if (step ==1 ) {/* Special case for 1..8bit widths */ while (height--) { -mga_writel (mmio,0 , *chardata); +#if defined(__BIG_ENDIAN) +fb_writel ((*chardata) <<24 , mmio.vaddr); +#else +fb_writel (*chardata, mmio.vaddr); +#endif chardata++; } }else if (step ==2 ) {/* Special case for 9..15bit widths */ while (height--) { -mga_writel (mmio,0 , *(u_int16_t *)chardata); +#if defined(__BIG_ENDIAN) +fb_writel ((*(u_int16_t *)chardata) <<16 , mmio.vaddr); +#else +fb_writel (*(u_int16_t *)chardata, mmio.vaddr); +#endif chardata +=2 ; } }else {
@@ -454,7 +462,7 @@for (i =0 ; i < step; i +=4 ) {/* Hope that there are at least three readable bytes beyond the end of bitmap */ -mga_writel (mmio,0 ,get_unaligned ((u_int32_t *)(chardata + i))); +fb_writel (get_unaligned ((u_int32_t *)(chardata + i)),mmio.vaddr); } chardata += step; }
drivers/video/matrox/matroxfb_base.h +2 -2
@@ -170,14 +170,14 @@if ((unsigned long )src &3 ) {while (len >=4 ) { -writel (get_unaligned ((u32 *)src), addr); +fb_writel (get_unaligned ((u32 *)src), addr); addr++; len -=4 ; src +=4 ; } }else {while (len >=4 ) { -writel (*(u32 *)src, addr); +fb_writel (*(u32 *)src, addr); addr++; len -=4 ; src +=4 ;
Re: [patch 06/16] Fix matroxfb on big-endian hardware
drivers/video/matrox/matroxfb_accel.c line 445
Quoted 6 lines · Chris Wright
drivers/video/matrox/matroxfb_accel.c +5
-1-mga_writel (mmio,0 , *chardata); +#if defined(__BIG_ENDIAN) +fb_writel ((*chardata) <<24 , mmio.vaddr); +#else +fb_writel (*chardata, mmio.vaddr); +#endif
So basically you are passing it cpu_to_le32(*chardata)?
drivers/video/matrox/matroxfb_accel.c line 455
Quoted 5 lines
drivers/video/matrox/matroxfb_accel.c +5
-0+#if defined(__BIG_ENDIAN) +fb_writel ((*(u_int16_t *)chardata) <<16 , mmio.vaddr); +#else +fb_writel (*(u_int16_t *)chardata, mmio.vaddr); +#endif
*yuck*
cpu_to_le32(le16_to_cpu(*(__le16 *)chardata)? Is that what you are doing here?
Re: [patch 06/16] Fix matroxfb on big-endian hardware
Quoted 18 lines · * Al Viro ([email protected]) wrote:
drivers/video/matrox/matroxfb_accel.c line 445
Quoted 6 lines · Chris Wright
drivers/video/matrox/matroxfb_accel.c +5
-1-mga_writel (mmio,0 , *chardata); +#if defined(__BIG_ENDIAN) +fb_writel ((*chardata) <<24 , mmio.vaddr); +#else +fb_writel (*chardata, mmio.vaddr); +#endif So basically you are passing it
cpu_to_le32(*chardata)?drivers/video/matrox/matroxfb_accel.c line 455
Quoted 5 lines
drivers/video/matrox/matroxfb_accel.c +5
-0+#if defined(__BIG_ENDIAN) +fb_writel ((*(u_int16_t *)chardata) <<16 , mmio.vaddr); +#else +fb_writel (*(u_int16_t *)chardata, mmio.vaddr); +#endif *yuck*
Quoted 2 lines
cpu_to_le32(le16_to_cpu(*(__le16 *)chardata)? Is that what you are doing here?
Petr, care to comment? Best I can tell this is from you and is already upstream. Any reason not to use cpu_to_xx instead of what's done?
Re: [patch 06/16] Fix matroxfb on big-endian hardware
Quoted 22 lines · Chris Wright
Quoted 20 lines · * Al Viro ([email protected]) wrote:
drivers/video/matrox/matroxfb_accel.c line 445
Quoted 6 lines · Chris Wright
drivers/video/matrox/matroxfb_accel.c +5
-1-mga_writel (mmio,0 , *chardata); +#if defined(__BIG_ENDIAN) +fb_writel ((*chardata) <<24 , mmio.vaddr); +#else +fb_writel (*chardata, mmio.vaddr); +#endif So basically you are passing it
cpu_to_le32(*chardata)?drivers/video/matrox/matroxfb_accel.c line 455
Quoted 5 lines
drivers/video/matrox/matroxfb_accel.c +5
-0+#if defined(__BIG_ENDIAN) +fb_writel ((*(u_int16_t *)chardata) <<16 , mmio.vaddr); +#else +fb_writel (*(u_int16_t *)chardata, mmio.vaddr); +#endif *yuck*
Quoted 2 lines
Quoted 2 lines
cpu_to_le32(le16_to_cpu(*(__le16 *)chardata)? Is that what you are doing here?
Yes. Hardware wants it this way. For 8bit wide font you must write font data in low 8 bits (some hardware on the way does swapping on BE archs), and for 16bit wide font you must write font data in low 16 bits. In both cases first pixel is in bit7 of byte 0, going through to bit0 of byte 0, followed by bit7 of byte 1 through bit0 of byte 1. And so on for widths > 16. Inner leX_to_cpu works on data of font size, while outer cpu_to_le32 works on accelerator data size, which is always 32 bit.
If you want it absolutely correct (as font data are in big endian), you should write cpu_to_le32(swab<font_width>(be<font_width>_to_cpup(chardata))). Inner be16_to_cpup retrieves font data into bits 15 -> 0, swab reorders bytes so first pixel is in bit 7, not bit 15 (or 31 for 32bit wide font), and outer cpu_to_le32 nullifies effect of external swab32() engine.
Quoted 2 lines
Petr, care to comment? Best I can tell this is from you and is already upstream. Any reason not to use
cpu_to_xxinstead of what's done?
I'm not sure about speed effects. Is gcc smart enough to notice that two different width byteswaps can be combined to simple shift?
Thanks,
Petr Vandrovec
PATCH 7/16 ide-disk: Fix LBA8 DMA
In reply to Chris WrightFrom: Daniel Drake <[email protected]>
This is from Gentoo's 2.6.11 patchset. A problem was introduced in 2.6.10 where some users could not enable DMA on their disks (particularly ALi15x3 users). This was a small mistake with the no_lba48_dma flag.
I can't find the exact commit but this is definately included in 2.6.12-rc4.
From: Bartlomiej Zolnierkiewicz <[email protected]>
--- drivers/ide/ide-disk.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletion(-)
drivers/ide/ide-disk.c +3 -1
@@ -133,6 +133,8 @@if (hwif->no_lba48_dma && lba48 && dma) {if (block + rq->nr_sectors >1ULL <<28 ) dma =0 ; +else + lba48 =0 ; }if (!dma) {
@@ -146,7 +148,7 @@/* FIXME: SELECT_MASK(drive, 0) ? */ if (drive->select.b.lba) { -if (drive->addressing ==1 ) { +if (lba48) {task_ioreg_t tasklets[10 ];pr_debug ("%s: LBA=0x%012llx\n" , drive->name, block);
PATCH 8/16 : Fix minor security hole
In reply to Chris WrightROSE wasn't verifying the ndigis argument of a new route resulting in a minor security hole.
--- net/rose/rose_route.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-)
net/rose/rose_route.c +2 -1
@@ -727,7 +727,8 @@ }if (rose_route.mask >10 )/* Mask can't be more than 10 digits */ return -EINVAL ; - +if (rose_route.ndigis >8 )/* No more than 8 digipeats */ +return -EINVAL ; err =rose_add_node (&rose_route, dev);dev_put (dev);return err;
PATCH 9/16 usbaudio: prevent oops & dead keyboard on usb unplugging
In reply to Chris WrightSummary: prevent oops & dead keyboard on usb unplugging while the device is being used
Without this patch, some usb kobjects, which are parents to the usx2y's kobjects can be freed before the usx2y's. This led to an oops in get_kobj_path_length() and a dead keyboard, when the usx2y's kobjects were freed. The patch ensures the correct sequence.
Tested ok on kernel 2.6.12-rc2.
Present in ALSA cvs
--- sound/usb/usbaudio.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
sound/usb/usbaudio.c +1 -1
@@ -3276,7 +3276,7 @@ } usb_chip[chip->index] =NULL ;up (®ister_mutex); -snd_card_free_in_thread (card); +snd_card_free (card); }else {up (®ister_mutex); }
PATCH 10/16 usbusx2y: prevent oops & dead keyboard on usb unplugging
In reply to Chris WrightSummary: prevent oops & dead keyboard on usb unplugging while the device is being used
Without this patch, some usb kobjects, which are parents to the usx2y's kobjects can be freed before the usx2y's. This led to an oops in get_kobj_path_length() and a dead keyboard, when the usx2y's kobjects were freed. The patch ensures the correct sequence.
Tested ok on kernel 2.6.12-rc2.
Present in ALSA cvs
--- sound/usb/usx2y/usbusx2y.c | 11 +++++++---- 1 files changed, 7 insertions(+), 4 deletions(-)
sound/usb/usx2y/usbusx2y.c +7 -4
@@ -1,6 +1,11 @@/* * usbusy2y.c - ALSA USB US-428 Driver * +2005-04-14 Karsten Wiese +Version 0.8.7.2: +Call snd_card_free() instead of snd_card_free_in_thread() to prevent oops with dead keyboard symptom. +Tested ok with kernel 2.6.12-rc2. +2004-12-14 Karsten Wiese Version 0.8.7.1: snd_pcm_open for rawusb pcm-devices now returns -EBUSY if called without rawusb's hwdep device being open.
@@ -143,7 +148,7 @@MODULE_AUTHOR ("Karsten Wiese <[email protected]>" ); -MODULE_DESCRIPTION ("TASCAM " NAME_ALLCAPS " Version 0.8.7.1" ); +MODULE_DESCRIPTION ("TASCAM " NAME_ALLCAPS " Version 0.8.7.2" );MODULE_LICENSE ("GPL" );MODULE_SUPPORTED_DEVICE ("{{TASCAM(0x1604), " NAME_ALLCAPS "(0x8001)(0x8005)(0x8007) }}" );
@@ -430,8 +435,6 @@if (ptr) {usX2Ydev_t * usX2Y =usX2Y ((snd_card_t *)ptr);struct list_head * p; -if (usX2Y->chip_status ==USX2Y_STAT_CHIP_HUP )// on 2.6.1 kernel snd_usbmidi_disconnect() -return ;// calls us back. better leave :-) . usX2Y->chip.shutdown =1 ; usX2Y->chip_status =USX2Y_STAT_CHIP_HUP ;usX2Y_unlinkSeq (&usX2Y->AS04);
@@ -443,7 +446,7 @@ }if (usX2Y->us428ctls_sharedmem)wake_up (&usX2Y->us428ctls_wait_queue_head); -snd_card_free_in_thread ((snd_card_t *)ptr); +snd_card_free ((snd_card_t *)ptr); } }
PATCH 11/16 USB: fix bug in visor driver with throttle/unthrottle causing oopses.
In reply to Chris WrightThanks to Mark Lord <[email protected]> for reporting this and helping with testing.
--- drivers/usb/serial/visor.c | 38 +++++++++++++++++++++++++++----------- 1 files changed, 27 insertions(+), 11 deletions(-)
drivers/usb/serial/visor.c +27 -11
@@ -386,6 +386,7 @@int bytes_in;int bytes_out;int outstanding_urbs; +int throttled; };/* number of outstanding urbs to prevent userspace DoS from happening */
@@ -415,6 +416,7 @@ priv->bytes_in =0 ; priv->bytes_out =0 ; priv->outstanding_urbs =0 ; + priv->throttled =0 ;spin_unlock_irqrestore (&priv->lock, flags);/*
@@ -602,6 +604,7 @@struct tty_struct *tty;unsigned long flags;int i; +int throttled;int result;dbg ("%s - port %d" , __FUNCTION__, port->number);
@@ -627,18 +630,21 @@ }spin_lock_irqsave (&priv->lock, flags); priv->bytes_in += urb->actual_length; + throttled = priv->throttled;spin_unlock_irqrestore (&priv->lock, flags); -/* Continue trying to always read */ -usb_fill_bulk_urb (port->read_urb, port->serial->dev, -usb_rcvbulkpipe (port->serial->dev, - port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, - port->read_urb->transfer_buffer_length, - visor_read_bulk_callback, port); - result =usb_submit_urb (port->read_urb,GFP_ATOMIC ); -if (result) -dev_err (&port->dev,"%s - failed resubmitting read urb, error %d\n" , __FUNCTION__, result); +/* Continue trying to always read if we should */ +if (!throttled) { +usb_fill_bulk_urb (port->read_urb, port->serial->dev, +usb_rcvbulkpipe (port->serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + visor_read_bulk_callback, port); + result =usb_submit_urb (port->read_urb,GFP_ATOMIC ); +if (result) +dev_err (&port->dev,"%s - failed resubmitting read urb, error %d\n" , __FUNCTION__, result); + }return ; }
@@ -683,16 +689,26 @@static void visor_throttle (struct usb_serial_port *port) { +struct visor_private *priv =usb_get_serial_port_data (port); +unsigned long flags; +dbg ("%s - port %d" , __FUNCTION__, port->number); -usb_kill_urb (port->read_urb); +spin_lock_irqsave (&priv->lock, flags); + priv->throttled =1 ; +spin_unlock_irqrestore (&priv->lock, flags); }static void visor_unthrottle (struct usb_serial_port *port) { +struct visor_private *priv =usb_get_serial_port_data (port); +unsigned long flags;int result;dbg ("%s - port %d" , __FUNCTION__, port->number); +spin_lock_irqsave (&priv->lock, flags); + priv->throttled =0 ; +spin_unlock_irqrestore (&priv->lock, flags); port->read_urb->dev = port->serial->dev; result =usb_submit_urb (port->read_urb,GFP_ATOMIC );
PATCH 12/16 x86_64: check if ptrace RIP is canonical
In reply to Chris Wright[PATCH] x86_64: check if ptrace RIP is canonical
This works around an AMD Erratum.
---
ptrace.c | 5 +++++ 1 files changed, 5 insertions(+)
arch/x86_64/kernel/ptrace.c +5 -0
@@ -149,6 +149,11 @@ static int putreg(struct task_struct *chreturn -EIO ; value &=0xffff ;break ; +case offsetof(struct user_regs_struct , rip): +/* Check if the new RIP address is canonical */ +if (value >=TASK_SIZE ) +return -EIO ; +break ; }put_stack_long (child, regno -sizeof (struct pt_regs ), value);return 0 ;
PATCH 13/16 x86_64: Fix canonical checking for segment registers in ptrace
In reply to Chris Wright[PATCH] x86_64: Fix canonical checking for segment registers in ptrace
Allowed user programs to set a non canonical segment base, which would cause oopses in the kernel later.
Credit-to: Alexander Nyberg <[email protected]>
For identifying and reporting this bug.
---
ptrace.c | 8 ++++---- 1 files changed, 4 insertions(+), 4 deletions(-)
arch/x86_64/kernel/ptrace.c +4 -4
@@ -129,13 +129,13 @@ static int putreg(struct task_struct *ch value &=0xffff ;return 0 ;case offsetof(struct user_regs_struct ,fs_base): -if (!((value >>48 ) ==0 || (value >>48 ) ==0xffff )) -return -EIO ; +if (value >=TASK_SIZE ) +return -EIO ; child->thread.fs = value;return 0 ;case offsetof(struct user_regs_struct ,gs_base): -if (!((value >>48 ) ==0 || (value >>48 ) ==0xffff )) -return -EIO ; +if (value >=TASK_SIZE ) +return -EIO ; child->thread.gs = value;return 0 ;case offsetof(struct user_regs_struct , eflags):
PATCH 14/16 x86_64: Add a guard page at the end of the 47bit address space
In reply to Chris Wright[PATCH] x86_64: Add a guard page at the end of the 47bit address space
This works around a bug in the AMD K8 CPUs.
---
processor.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
include/asm-x86_64/processor.h +2 -2
@@ -160,9 +160,9 @@ static inline void clear_in_cr4 (unsigne/* -* User space process size. 47bits. +* User space process size. 47bits minus one guard page. */ -#define TASK_SIZE (0x800000000000UL) +#define TASK_SIZE (0x800000000000UL - 4096)/* This decides where the kernel will search for a free chunk of vm * space during mmap's.
PATCH 15/16 x86_64: When checking vmalloc mappings don't use pte_page
In reply to Chris Wright[PATCH] x86_64: When checking vmalloc mappings don't use pte_page
The PTEs can point to ioremap mappings too, and these are often outside mem_map. The NUMA hash page lookup functions cannot handle out of bounds accesses properly.
---
fault.c | 11 +++++++++-- 1 files changed, 9 insertions(+), 2 deletions(-)
arch/x86_64/mm/fault.c +9 -2
@@ -236,6 +236,8 @@ static noinline void pgtable_bad(unsigne/* * Handle a fault on the vmalloc or module mapping area +* +* This assumes no large pages in there. */ static int vmalloc_fault (unsigned long address) {
@@ -274,7 +276,10 @@ static int vmalloc_fault(unsigned long aif (!pte_present (*pte_ref))return -1 ; pte =pte_offset_kernel (pmd, address); -if (!pte_present (*pte) ||pte_page (*pte) !=pte_page (*pte_ref)) +/* Don't use pte_page here, because the mappings can point +outside mem_map, and the NUMA hash lookup cannot handle +that. */ +if (!pte_present (*pte) ||pte_pfn (*pte) !=pte_pfn (*pte_ref))BUG ();__flush_tlb_all ();return 0 ;
@@ -348,7 +353,9 @@ asmlinkage void do_page_fault(struct pt_* protection error (error_code & 1) == 0. */ if (unlikely (address >=TASK_SIZE )) { -if (!(error_code &5 )) { +if (!(error_code &5 ) && + ((address >=VMALLOC_START && address <VMALLOC_END ) || + (address >=MODULES_VADDR && address <MODULES_END ))) {if (vmalloc_fault (address) <0 ) goto bad_area_nosemaphore;return ;
PATCH 16/16 x86_64: Don't look up struct page pointer of physical address in iounmap
In reply to Chris Wright[PATCH] x86_64: Don't look up struct page pointer of physical address in iounmap
It could be in a memory hole not mapped in mem_map and that causes the hash lookup to go off to nirvana.
Back port to -stable tree by Chris Wright
---
ioremap.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-)
arch/x86_64/mm/ioremap.c +1 -1
@@ -266,7 +266,7 @@ void iounmap(volatile void __iomem *addrif ((p->flags >>20 ) && p->phys_addr + p->size -1 <virt_to_phys (high_memory)) {/* p->size includes the guard page, but cpa doesn't like that */ -change_page_attr (virt_to_page (__va (p->phys_addr)), +change_page_attr_addr ((unsigned long )(__va (p->phys_addr)), (p->size -PAGE_SIZE ) >>PAGE_SHIFT ,PAGE_KERNEL );global_flush_tlb ();