Skip to contentSkip to conversation

-stable review

PATCH In review Chris Wright 6 participants 23 messages May 23, 2005 – May 31, 2005

Subsystems (11)
lore
Share & tools
lore
#0 lore raw

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...)

#1 lore raw

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

#2 lore raw

PATCH 2/16 3c59x: only put the device into D3 when we're actually using WOL

In reply to Chris Wright

During 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);
 }
 
 
#3 lore raw

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.

---
 drivers/net/3c59x.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

--- linux-2.6.11.10.orig/drivers/net/3c59x.c 2005-05-20 09:34:18.788560304
-0700 +++ linux-2.6.11.10/drivers/net/3c59x.c 2005-05-20 09:34:22.644974040
-0700 @@ -1581,7 +1581,8 @@

drivers/net/3c59x.c +6 -3
 	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);
 }
#4 lore raw

PATCH 3/16 : Fix smp race.

In reply to Chris Wright

The 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)
#5 lore raw

PATCH 4/16 ext3: fix race between ext3 make block reservation and reservation window discard

In reply to Chris Wright

This 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);
 	}
 }
#6 lore raw

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

#7 lore raw

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 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

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

#8 lore raw

PATCH 5/16 PPC64: Fix LPAR IOMMU setup code for p630

In reply to Chris Wright

Here'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();
 }
#9 lore raw

PATCH 6/16 Fix matroxfb on big-endian hardware

In reply to Chris Wright

There 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;
#10 lore raw

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?

#11 lore raw

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?

#12 lore raw

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_xx instead 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

#13 lore raw

PATCH 7/16 ide-disk: Fix LBA8 DMA

In reply to Chris Wright

From: 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);
#14 lore raw

PATCH 8/16 : Fix minor security hole

In reply to Chris Wright

ROSE 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;
#15 lore raw

PATCH 9/16 usbaudio: prevent oops & dead keyboard on usb unplugging

In reply to Chris Wright

Summary: 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(&register_mutex);
-		snd_card_free_in_thread(card);
+		snd_card_free(card);
 	} else {
 		up(&register_mutex);
 	}
#16 lore raw

PATCH 10/16 usbusx2y: prevent oops & dead keyboard on usb unplugging

In reply to Chris Wright

Summary: 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);
 	}
 }
 
#17 lore raw

PATCH 11/16 USB: fix bug in visor driver with throttle/unthrottle causing oopses.

In reply to Chris Wright

Thanks 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);
#18 lore raw

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
Index: release-2.6.11/arch/x86_64/kernel/ptrace.c
===================================================================
@@ -149,6 +149,11 @@ static int putreg(struct task_struct *ch
 				return -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;
#19 lore raw

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
Index: release-2.6.11/arch/x86_64/kernel/ptrace.c
===================================================================
@@ -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):
#20 lore raw

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
Index: release-2.6.11/include/asm-x86_64/processor.h
===================================================================
@@ -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.
#21 lore raw

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
Index: release-2.6.11/arch/x86_64/mm/fault.c
===================================================================
@@ -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 a
 	if (!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;
#22 lore raw

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
Index: release-2.6.11/arch/x86_64/mm/ioremap.c
===================================================================
@@ -266,7 +266,7 @@ void iounmap(volatile void __iomem *addr
 	if ((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();