Skip to contentSkip to conversation

2.6.26-stable review

PATCH In review Greg KH 3 participants 113 messages Aug 18, 2008 – Aug 19, 2008

Subsystems (31)
lore
Share & tools
lore

Greg KH

author
#0 lore raw

cover 2.6.26-stable review

This is the start of the stable review cycle for the 2.6.26.3 release. There are 60 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, August 20, 17:00:00 UTC. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.26.3-rc1.gz

and the diffstat can be found below.

thanks,

the -stable release team

 Makefile                              |    2 +-
 arch/ia64/kvm/kvm-ia64.c              |    5 +-
 arch/sparc64/kernel/irq.c             |   52 +++++++
 arch/sparc64/kernel/kstack.h          |   60 ++++++++
 arch/sparc64/kernel/process.c         |   32 +++--
 arch/sparc64/kernel/signal.c          |    6 +-
 arch/sparc64/kernel/stacktrace.c      |   11 +-
 arch/sparc64/kernel/traps.c           |    7 +-
 arch/sparc64/lib/mcount.S             |   39 +++++-
 arch/sparc64/mm/init.c                |   11 ++
 arch/sparc64/mm/ultra.S               |    7 +
 arch/x86/boot/boot.h                  |    8 +
 arch/x86/boot/cpucheck.c              |    8 +-
 arch/x86/boot/main.c                  |    4 +
 arch/x86/kernel/cpu/mtrr/generic.c    |    2 +-
 arch/x86/kvm/mmu.c                    |    1 +
 arch/x86/kvm/svm.c                    |    7 +-
 arch/x86/kvm/vmx.c                    |    2 +
 arch/x86/kvm/x86.c                    |  109 ++++++---------
 arch/x86/pci/k8-bus_64.c              |    4 +-
 block/scsi_ioctl.c                    |    2 +-
 drivers/char/hw_random/via-rng.c      |    8 +
 drivers/crypto/padlock-aes.c          |   28 ++++-
 drivers/crypto/padlock-sha.c          |    9 ++
 drivers/i2c/Kconfig                   |   14 ++
 drivers/i2c/algos/Kconfig             |   11 +-
 drivers/i2c/i2c-core.c                |    4 +-
 drivers/ide/ide-cd.c                  |   18 ++-
 drivers/ide/pci/cs5520.c              |    1 +
 drivers/ide/pci/it821x.c              |    6 +
 drivers/misc/acer-wmi.c               |   19 +++
 drivers/net/r8169.c                   |    6 +-
 drivers/net/wireless/rtl8187.h        |    4 +
 drivers/net/wireless/rtl8187_dev.c    |    3 +
 drivers/pci/quirks.c                  |    7 +-
 drivers/scsi/hptiop.c                 |    7 +
 drivers/scsi/qla2xxx/qla_attr.c       |   43 ++++--
 drivers/scsi/qla2xxx/qla_def.h        |    1 -
 drivers/scsi/qla2xxx/qla_gbl.h        |    2 +
 drivers/scsi/qla2xxx/qla_init.c       |   16 +--
 drivers/scsi/qla2xxx/qla_os.c         |   55 ++++++--
 drivers/scsi/scsi_transport_spi.c     |    8 +-
 drivers/scsi/ses.c                    |   18 ++-
 drivers/usb/core/message.c            |    2 +-
 drivers/usb/serial/ftdi_sio.c         |    5 +
 drivers/usb/serial/ftdi_sio.h         |    6 +
 drivers/usb/serial/pl2303.c           |    1 -
 drivers/usb/serial/pl2303.h           |    4 -
 drivers/usb/serial/usb-serial.c       |    7 +-
 drivers/usb/storage/scsiglue.c        |   25 ++--
 drivers/usb/storage/transport.c       |   17 ++-
 drivers/usb/storage/unusual_devs.h    |   18 ++-
 drivers/video/arkfb.c                 |   18 ++--
 drivers/video/aty/radeon_accel.c      |   12 ++-
 drivers/video/matrox/matroxfb_maven.c |    2 +-
 drivers/video/s3fb.c                  |   18 ++--
 drivers/video/vt8623fb.c              |   20 ++--
 fs/cifs/asn1.c                        |    2 +-
 fs/cifs/cifs_spnego.c                 |   18 ++-
 fs/cifs/cifsfs.c                      |    2 +
 fs/cifs/inode.c                       |    1 +
 include/asm-sparc64/futex.h           |    2 +-
 include/asm-sparc64/irq.h             |    4 +
 include/asm-sparc64/ptrace.h          |    8 +-
 include/asm-x86/i387.h                |   32 +++++
 include/asm-x86/spinlock.h            |    4 +-
 include/linux/usb/serial.h            |    3 +-
 include/video/radeon.h                |    9 +-
 kernel/posix-timers.c                 |   19 ++-
 kernel/relay.c                        |   12 ++-
 kernel/signal.c                       |    1 +
 lib/random32.c                        |   48 ++++---
 mm/memory.c                           |   16 ++-
 mm/mlock.c                            |    2 -
 net/dccp/proto.c                      |    5 +
 net/ipv4/ipvs/ip_vs_est.c             |    7 +-
 net/ipv4/syncookies.c                 |    1 +
 net/ipv6/ip6_output.c                 |    4 +
 net/ipv6/syncookies.c                 |    1 +
 sound/soc/fsl/fsl_dma.c               |  242 ++++++++++++++++++---------------
 sound/soc/fsl/fsl_ssi.c               |   74 +++++++++--
 81 files changed, 940 insertions(+), 399 deletions(-)
 create mode 100644 arch/sparc64/kernel/kstack.h
author
#1 lore raw

PATCH 1/60 mlock() fix return values

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

------------------
From: KOSAKI Motohiro <[email protected]>

commit a477097d9c37c1cf289c7f0257dffcfa42d50197 upstream

Halesh says:

Please find the below testcase provide to test mlock.

Test Case :
===========================

#include <sys/resource.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>

int main(void)
{
int fd,ret, i = 0;
char *addr, *addr1 = NULL;
unsigned int page_size;
struct rlimit rlim;

  if (0 != geteuid())
  {
   printf("Execute this pgm as root\n");
   exit(1);
  }

  /* create a file */
  if ((fd = open("mmap_test.c",O_RDWR|O_CREAT,0755)) == -1)
  {
   printf("cant create test file\n");
   exit(1);
  }

  page_size = sysconf(_SC_PAGE_SIZE);

  /* set the MEMLOCK limit */
  rlim.rlim_cur = 2000;
  rlim.rlim_max = 2000;

  if ((ret = setrlimit(RLIMIT_MEMLOCK,&rlim)) != 0)
  {
   printf("Cant change limit values\n");
   exit(1);
  }

addr = 0;
while (1)
{
/* map a page into memory each time*/
if ((addr = (char *) mmap(addr,page_size, PROT_READ |
PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED)
{
printf("cant do mmap on file\n");
exit(1);
}

if (0 == i)

    addr1 = addr;

i++;
errno = 0;
/* lock the mapped memory pagewise*/
if ((ret = mlock((char *)addr, 1500)) == -1)
{
printf("errno value is %d\n", errno);
printf("cant lock maped region\n");
exit(1);
}
addr = addr + page_size;
}
}
======================================================

This testcase results in an mlock() failure with errno 14 that is EFAULT, but it has nowhere been specified that mlock() will return EFAULT. When I tested the same on older kernels like 2.6.18, I got the correct result i.e errno 12 (ENOMEM).

I think in source code mlock(2), setting errno ENOMEM has been missed in do_mlock() , on mlock_fixup() failure.

SUSv3 requires the following behavior frmo mlock(2).

[ENOMEM]
Some or all of the address range specified by the addr and len arguments does not correspond to valid mapped pages in the address space of the process.

[EAGAIN]
Some or all of the memory identified by the operation could not be locked when the call was made.

This rule isn't so nice and slighly strange. but many people think POSIX/SUS compliance is important.

---
 mm/memory.c |   16 +++++++++++++---
 mm/mlock.c  |    2 --
 2 files changed, 13 insertions(+), 5 deletions(-)
mm/memory.c +13 -3
@@ -2748,16 +2748,26 @@ int make_pages_present(unsigned long add
 
 	vma = find_vma(current->mm, addr);
 	if (!vma)
-		return -1;
+		return -ENOMEM;
 	write = (vma->vm_flags & VM_WRITE) != 0;
 	BUG_ON(addr >= end);
 	BUG_ON(end > vma->vm_end);
 	len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE;
 	ret = get_user_pages(current, current->mm, addr,
 			len, write, 0, NULL, NULL);
-	if (ret < 0)
+	if (ret < 0) {
+		/*
+		   SUS require strange return value to mlock
+		    - invalid addr generate to ENOMEM.
+		    - out of memory should generate EAGAIN.
+		*/
+		if (ret == -EFAULT)
+			ret = -ENOMEM;
+		else if (ret == -ENOMEM)
+			ret = -EAGAIN;
 		return ret;
-	return ret == len ? 0 : -1;
+	}
+	return ret == len ? 0 : -ENOMEM;
 }
 
 #if !defined(__HAVE_ARCH_GATE_AREA)
mm/mlock.c +0 -2
@@ -78,8 +78,6 @@ success:
 
 	mm->locked_vm -= pages;
 out:
-	if (ret == -ENOMEM)
-		ret = -EAGAIN;
 	return ret;
 }
 
author
#2 lore raw

PATCH 2/60 SCSI: ses: fix VPD inquiry overrun

In reply to Greg KH

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

------------------
From: James Bottomley <[email protected]>

commit 671a99c8eb2f1dde08ac5538d8cd912047c61ddf upstream

There are a few kerneloops.org reports like this one:

http://www.kerneloops.org/search.php?search=ses_match_to_enclosure

That seem to imply we're running off the end of the VPD inquiry data (although at 512 bytes, it should be long enough for just about anything). we should be using correctly sized buffers anyway, so put those in and hope this oops goes away.

---
 drivers/scsi/ses.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/scsi/ses.c +14 -4
@@ -345,14 +345,14 @@ static int ses_enclosure_find_by_addr(st
 	return 0;
 }
 
-#define VPD_INQUIRY_SIZE 512
+#define VPD_INQUIRY_SIZE 36
 
 static void ses_match_to_enclosure(struct enclosure_device *edev,
 				   struct scsi_device *sdev)
 {
 	unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL);
 	unsigned char *desc;
-	int len;
+	u16 vpd_len;
 	struct efd efd = {
 		.addr = 0,
 	};
@@ -372,9 +372,19 @@ static void ses_match_to_enclosure(struc
 			     VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES))
 		goto free;
 
-	len = (buf[2] << 8) + buf[3];
+	vpd_len = (buf[2] << 8) + buf[3];
+	kfree(buf);
+	buf = kmalloc(vpd_len, GFP_KERNEL);
+	if (!buf)
+		return;
+	cmd[3] = vpd_len >> 8;
+	cmd[4] = vpd_len & 0xff;
+	if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf,
+			     vpd_len, NULL, SES_TIMEOUT, SES_RETRIES))
+		goto free;
+
 	desc = buf + 4;
-	while (desc < buf + len) {
+	while (desc < buf + vpd_len) {
 		enum scsi_protocol proto = desc[0] >> 4;
 		u8 code_set = desc[0] & 0x0f;
 		u8 piv = desc[1] & 0x80;
author
#3 lore raw

PATCH 3/60 SCSI: scsi_transport_spi: fix oops in revalidate

In reply to Greg KH

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

------------------
From: James Bottomley <[email protected]>

commit e8bac9e0647dd04c83fd0bfe7cdfe2f6dfb100d0 upstream

The class_device->device conversion is causing an oops in revalidate because it's assuming that the device_for_each_child iterator will only return struct scsi_device children. The conversion made all former class_devices children of the device as well, so this assumption is broken. Fix it.

---
 drivers/scsi/scsi_transport_spi.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/scsi/scsi_transport_spi.c +5 -3
@@ -366,12 +366,14 @@ spi_transport_rd_attr(rti, "%d\n");
 spi_transport_rd_attr(pcomp_en, "%d\n");
 spi_transport_rd_attr(hold_mcs, "%d\n");
 
-/* we only care about the first child device so we return 1 */
+/* we only care about the first child device that's a real SCSI device
+ * so we return 1 to terminate the iteration when we find it */
 static int child_iter(struct device *dev, void *data)
 {
-	struct scsi_device *sdev = to_scsi_device(dev);
+	if (!scsi_is_sdev_device(dev))
+		return 0;
 
-	spi_dv_device(sdev);
+	spi_dv_device(to_scsi_device(dev));
 	return 1;
 }
 
author
#4 lore raw

PATCH 4/60 SCSI: block: Fix miscalculation of sg_io timeout in CDROM_SEND_PACKET handler.

In reply to Greg KH

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

------------------
From: Tim Wright <[email protected]>

commit ad337591f4fd20de6a0ca03d6715267a5c1d2b16 upstream

It seems cdrwtool in the udftools has been unusable on "modern" kernels for some time. A Google search reveals many people with the same issue but no solution (cdrwtool fails to format the disk). After spending some time tracking down the issue, it comes down to the following:

The udftools still use the older CDROM_SEND_PACKET interface to send things like FORMAT_UNIT through to the drive. They should really be updated, but that's another story. Since most distros are using libata now, the cd or dvd burner appears as a SCSI device, and we wind up in block/scsi_ioctl.c. Here, the code tries to take the "struct cdrom_generic_command" and translate it and stuff it into a "struct sg_io_hdr" structure so it can pass it to the modern sg_io() routine instead. Unfortunately, there is one error, or rather an omission in the translation. The timeout that is passed in in the "struct cdrom_generic_command" is in HZ=100 units, and this is modified and correctly converted to jiffies by use of clock_t_to_jiffies(). However, a little further down, this cgc.timeout value in jiffies is simply copied into the sg_io_hdr timeout, which should be in milliseconds. Since most modern x86 kernels seems to be getting build with HZ=250, the timeout that is passed to sg_io and eventually converted to the timeout_per_command member of the scsi_cmnd structure is now four times too small. Since cdrwtool tries to set the timeout to one hour for the FORMAT_UNIT command, and it takes about 20 minutes to format a 4x CDRW, the SCSI error-handler kicks in after the FORMAT_UNIT completes because it took longer than the incorrectly-calculated timeout.

---
 block/scsi_ioctl.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
block/scsi_ioctl.c +1 -1
@@ -629,7 +629,7 @@ int scsi_cmd_ioctl(struct file *file, st
 			hdr.sbp = cgc.sense;
 			if (hdr.sbp)
 				hdr.mx_sb_len = sizeof(struct request_sense);
-			hdr.timeout = cgc.timeout;
+			hdr.timeout = jiffies_to_msecs(cgc.timeout);
 			hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
 			hdr.cmd_len = sizeof(cgc.cmd);
 
author
#5 lore raw

PATCH 5/60 SCSI: hptiop: add more PCI device IDs

In reply to Greg KH

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

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

commit dd07428b44944b42f699408fe31af47977f1e733 upstream

Add PCI device ID for new adapter models.

---
 drivers/scsi/hptiop.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/scsi/hptiop.c +7 -0
@@ -1249,6 +1249,13 @@ static struct pci_device_id hptiop_id_ta
 	{ PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4311), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops },
 	{ PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops },
 	{ PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops },
author
#6 lore raw

PATCH 6/60 vt8623fb: fix kernel oops

In reply to Greg KH

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

------------------
From: Ondrej Zajicek <[email protected]>

commit 594a8819774b09ee5bf72d23300489459ff1f882 upstream

commit 20e061fb750d36ec0ffcb2e44ed7dafa9018223b
Author: Ondrej Zajicek <[email protected]>
Date: Mon Apr 28 02:15:18 2008 -0700

fbdev: framebuffer_alloc() fixes

Correct the dev arg of framebuffer_alloc() in arkfb, s3fb and vt8623fb.

causes a null-pointer deref because "info->dev is NULL, info was just kzallocated".

---
 drivers/video/arkfb.c    |   18 +++++++++---------
 drivers/video/s3fb.c     |   18 +++++++++---------
 drivers/video/vt8623fb.c |   20 ++++++++++----------
 3 files changed, 28 insertions(+), 28 deletions(-)
drivers/video/arkfb.c +9 -9
@@ -958,20 +958,20 @@ static int __devinit ark_pci_probe(struc
 	/* Prepare PCI device */
 	rc = pci_enable_device(dev);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot enable PCI device\n");
+		dev_err(info->device, "cannot enable PCI device\n");
 		goto err_enable_device;
 	}
 
 	rc = pci_request_regions(dev, "arkfb");
 	if (rc < 0) {
-		dev_err(info->dev, "cannot reserve framebuffer region\n");
+		dev_err(info->device, "cannot reserve framebuffer region\n");
 		goto err_request_regions;
 	}
 
 	par->dac = ics5342_init(ark_dac_read_regs, ark_dac_write_regs, info);
 	if (! par->dac) {
 		rc = -ENOMEM;
-		dev_err(info->dev, "RAMDAC initialization failed\n");
+		dev_err(info->device, "RAMDAC initialization failed\n");
 		goto err_dac;
 	}
 
@@ -982,7 +982,7 @@ static int __devinit ark_pci_probe(struc
 	info->screen_base = pci_iomap(dev, 0, 0);
 	if (! info->screen_base) {
 		rc = -ENOMEM;
-		dev_err(info->dev, "iomap for framebuffer failed\n");
+		dev_err(info->device, "iomap for framebuffer failed\n");
 		goto err_iomap;
 	}
 
@@ -1004,19 +1004,19 @@ static int __devinit ark_pci_probe(struc
 	rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
 	if (! ((rc == 1) || (rc == 2))) {
 		rc = -EINVAL;
-		dev_err(info->dev, "mode %s not found\n", mode_option);
+		dev_err(info->device, "mode %s not found\n", mode_option);
 		goto err_find_mode;
 	}
 
 	rc = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot allocate colormap\n");
+		dev_err(info->device, "cannot allocate colormap\n");
 		goto err_alloc_cmap;
 	}
 
 	rc = register_framebuffer(info);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot register framebugger\n");
+		dev_err(info->device, "cannot register framebugger\n");
 		goto err_reg_fb;
 	}
 
@@ -1090,7 +1090,7 @@ static int ark_pci_suspend (struct pci_d
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct arkfb_info *par = info->par;
 
-	dev_info(info->dev, "suspend\n");
+	dev_info(info->device, "suspend\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
@@ -1121,7 +1121,7 @@ static int ark_pci_resume (struct pci_de
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct arkfb_info *par = info->par;
 
-	dev_info(info->dev, "resume\n");
+	dev_info(info->device, "resume\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
drivers/video/s3fb.c +9 -9
@@ -903,13 +903,13 @@ static int __devinit s3_pci_probe(struct
 	/* Prepare PCI device */
 	rc = pci_enable_device(dev);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot enable PCI device\n");
+		dev_err(info->device, "cannot enable PCI device\n");
 		goto err_enable_device;
 	}
 
 	rc = pci_request_regions(dev, "s3fb");
 	if (rc < 0) {
-		dev_err(info->dev, "cannot reserve framebuffer region\n");
+		dev_err(info->device, "cannot reserve framebuffer region\n");
 		goto err_request_regions;
 	}
 
@@ -921,7 +921,7 @@ static int __devinit s3_pci_probe(struct
 	info->screen_base = pci_iomap(dev, 0, 0);
 	if (! info->screen_base) {
 		rc = -ENOMEM;
-		dev_err(info->dev, "iomap for framebuffer failed\n");
+		dev_err(info->device, "iomap for framebuffer failed\n");
 		goto err_iomap;
 	}
 
@@ -965,19 +965,19 @@ static int __devinit s3_pci_probe(struct
 	rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
 	if (! ((rc == 1) || (rc == 2))) {
 		rc = -EINVAL;
-		dev_err(info->dev, "mode %s not found\n", mode_option);
+		dev_err(info->device, "mode %s not found\n", mode_option);
 		goto err_find_mode;
 	}
 
 	rc = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot allocate colormap\n");
+		dev_err(info->device, "cannot allocate colormap\n");
 		goto err_alloc_cmap;
 	}
 
 	rc = register_framebuffer(info);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot register framebuffer\n");
+		dev_err(info->device, "cannot register framebuffer\n");
 		goto err_reg_fb;
 	}
 
@@ -1053,7 +1053,7 @@ static int s3_pci_suspend(struct pci_dev
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct s3fb_info *par = info->par;
 
-	dev_info(info->dev, "suspend\n");
+	dev_info(info->device, "suspend\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
@@ -1085,7 +1085,7 @@ static int s3_pci_resume(struct pci_dev*
 	struct s3fb_info *par = info->par;
 	int err;
 
-	dev_info(info->dev, "resume\n");
+	dev_info(info->device, "resume\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
@@ -1102,7 +1102,7 @@ static int s3_pci_resume(struct pci_dev*
 	if (err) {
 		mutex_unlock(&(par->open_lock));
 		release_console_sem();
-		dev_err(info->dev, "error %d enabling device for resume\n", err);
+		dev_err(info->device, "error %d enabling device for resume\n", err);
 		return err;
 	}
 	pci_set_master(dev);
drivers/video/vt8623fb.c +10 -10
@@ -677,13 +677,13 @@ static int __devinit vt8623_pci_probe(st
 
 	rc = pci_enable_device(dev);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot enable PCI device\n");
+		dev_err(info->device, "cannot enable PCI device\n");
 		goto err_enable_device;
 	}
 
 	rc = pci_request_regions(dev, "vt8623fb");
 	if (rc < 0) {
-		dev_err(info->dev, "cannot reserve framebuffer region\n");
+		dev_err(info->device, "cannot reserve framebuffer region\n");
 		goto err_request_regions;
 	}
 
@@ -696,14 +696,14 @@ static int __devinit vt8623_pci_probe(st
 	info->screen_base = pci_iomap(dev, 0, 0);
 	if (! info->screen_base) {
 		rc = -ENOMEM;
-		dev_err(info->dev, "iomap for framebuffer failed\n");
+		dev_err(info->device, "iomap for framebuffer failed\n");
 		goto err_iomap_1;
 	}
 
 	par->mmio_base = pci_iomap(dev, 1, 0);
 	if (! par->mmio_base) {
 		rc = -ENOMEM;
-		dev_err(info->dev, "iomap for MMIO failed\n");
+		dev_err(info->device, "iomap for MMIO failed\n");
 		goto err_iomap_2;
 	}
 
@@ -714,7 +714,7 @@ static int __devinit vt8623_pci_probe(st
 	if ((16 <= memsize1) && (memsize1 <= 64) && (memsize1 == memsize2))
 		info->screen_size = memsize1 << 20;
 	else {
-		dev_err(info->dev, "memory size detection failed (%x %x), suppose 16 MB\n", memsize1, memsize2);
+		dev_err(info->device, "memory size detection failed (%x %x), suppose 16 MB\n", memsize1, memsize2);
 		info->screen_size = 16 << 20;
 	}
 
@@ -731,19 +731,19 @@ static int __devinit vt8623_pci_probe(st
 	rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
 	if (! ((rc == 1) || (rc == 2))) {
 		rc = -EINVAL;
-		dev_err(info->dev, "mode %s not found\n", mode_option);
+		dev_err(info->device, "mode %s not found\n", mode_option);
 		goto err_find_mode;
 	}
 
 	rc = fb_alloc_cmap(&info->cmap, 256, 0);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot allocate colormap\n");
+		dev_err(info->device, "cannot allocate colormap\n");
 		goto err_alloc_cmap;
 	}
 
 	rc = register_framebuffer(info);
 	if (rc < 0) {
-		dev_err(info->dev, "cannot register framebugger\n");
+		dev_err(info->device, "cannot register framebugger\n");
 		goto err_reg_fb;
 	}
 
@@ -817,7 +817,7 @@ static int vt8623_pci_suspend(struct pci
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct vt8623fb_info *par = info->par;
 
-	dev_info(info->dev, "suspend\n");
+	dev_info(info->device, "suspend\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
@@ -848,7 +848,7 @@ static int vt8623_pci_resume(struct pci_
 	struct fb_info *info = pci_get_drvdata(dev);
 	struct vt8623fb_info *par = info->par;
 
-	dev_info(info->dev, "resume\n");
+	dev_info(info->device, "resume\n");
 
 	acquire_console_sem();
 	mutex_lock(&(par->open_lock));
author
#7 lore raw

PATCH 7/60 relay: fix "full buffer with exactly full last subbuffer" accounting problem

In reply to Greg KH

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

------------------
From: Tom Zanussi <[email protected]>

commit 32194450330be327f3b25bf6b66298bd122599e9 upstream

In relay's current read implementation, if the buffer is completely full but hasn't triggered the buffer-full condition (i.e. the last write didn't cross the subbuffer boundary) and the last subbuffer is exactly full, the subbuffer accounting code erroneously finds nothing available. This patch fixes the problem.

Cc Eduard - Gabriel Munteanu <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Jens Axboe <[email protected]>
Cc Mathieu Desnoyers <[email protected]>
Cc Andrea Righi <[email protected]>
---
 kernel/relay.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
kernel/relay.c +11 -1
@@ -832,6 +832,10 @@ static void relay_file_read_consume(stru
 	size_t n_subbufs = buf->chan->n_subbufs;
 	size_t read_subbuf;
 
+	if (buf->subbufs_produced == buf->subbufs_consumed &&
+	    buf->offset == buf->bytes_consumed)
+		return;
+
 	if (buf->bytes_consumed + bytes_consumed > subbuf_size) {
 		relay_subbufs_consumed(buf->chan, buf->cpu, 1);
 		buf->bytes_consumed = 0;
@@ -863,6 +867,8 @@ static int relay_file_read_avail(struct 
 
 	relay_file_read_consume(buf, read_pos, 0);
 
+	consumed = buf->subbufs_consumed;
+
 	if (unlikely(buf->offset > subbuf_size)) {
 		if (produced == consumed)
 			return 0;
@@ -881,8 +887,12 @@ static int relay_file_read_avail(struct 
 	if (consumed > produced)
 		produced += n_subbufs * subbuf_size;
 
-	if (consumed == produced)
+	if (consumed == produced) {
+		if (buf->offset == subbuf_size &&
+		    buf->subbufs_produced > buf->subbufs_consumed)
+			return 1;
 		return 0;
+	}
 
 	return 1;
 }
author
#8 lore raw

PATCH 8/60 ide-cd: fix endianity for the error message in cdrom_read_capacity

In reply to Greg KH

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

------------------
From: Petr Tesarik <[email protected]>

commit 938bb03d188a1e688fb0bcae49788f540193e80a uptream

Aesthetic regards aside, commit e8e7b9eb11c34ee18bde8b7011af41938d1ad667 still leaves a bug in the error message, because it uses the unconverted big-endian value for printk.

Fix this by using a local variable in machine byte order. The result is correct, more readable, and also produces slightly shorter code on i386.

---
 drivers/ide/ide-cd.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/ide/ide-cd.c +10 -8
@@ -1298,6 +1298,7 @@ static int cdrom_read_capacity(ide_drive
 
 	int stat;
 	struct request req;
+	u32 blocklen;
 
 	ide_cd_init_rq(drive, &req);
 
@@ -1314,23 +1315,24 @@ static int cdrom_read_capacity(ide_drive
 	/*
 	 * Sanity check the given block size
 	 */
-	switch (capbuf.blocklen) {
-	case __constant_cpu_to_be32(512):
-	case __constant_cpu_to_be32(1024):
-	case __constant_cpu_to_be32(2048):
-	case __constant_cpu_to_be32(4096):
+	blocklen = be32_to_cpu(capbuf.blocklen);
+	switch (blocklen) {
+	case 512:
+	case 1024:
+	case 2048:
+	case 4096:
 		break;
 	default:
 		printk(KERN_ERR "%s: weird block size %u\n",
-			drive->name, capbuf.blocklen);
+			drive->name, blocklen);
 		printk(KERN_ERR "%s: default to 2kb block size\n",
 			drive->name);
-		capbuf.blocklen = __constant_cpu_to_be32(2048);
+		blocklen = 2048;
 		break;
 	}
 
 	*capacity = 1 + be32_to_cpu(capbuf.lba);
-	*sectors_per_frame = be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
+	*sectors_per_frame = blocklen >> SECTOR_BITS;
 	return 0;
 }
 
author
#9 lore raw

PATCH 9/60 posix-timers: do_schedule_next_timer: fix the setting of ->si_overrun

In reply to Greg KH

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

------------------
From: Oleg Nesterov <[email protected]>

commit 54da1174922cddd4be83d5a364b2e0fdd693f513 upstream

do_schedule_next_timer() sets info->si_overrun = timr->it_overrun_last, this discards the already accumulated overruns.

Cc Mark McLoughlin <[email protected]>
Cc Oliver Pinter <[email protected]>
Cc Roland McGrath <[email protected]>
Cc Andrew Morton <[email protected]>
---
 kernel/posix-timers.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/posix-timers.c +1 -1
@@ -289,7 +289,7 @@ void do_schedule_next_timer(struct sigin
 		else
 			schedule_next_timer(timr);
 
-		info->si_overrun = timr->it_overrun_last;
+		info->si_overrun += timr->it_overrun_last;
 	}
 
 	if (timr)
author
#10 lore raw

PATCH 10/60 posix-timers: fix posix_timer_event() vs dequeue_signal() race

In reply to Greg KH

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

------------------
From: Oleg Nesterov <[email protected]>

commit ba661292a2bc6ddd305a212b0526e5dc22195fe7 upstream

The bug was reported and analysed by Mark McLoughlin <[email protected]>, the patch is based on his and Roland's suggestions.

posix_timer_event() always rewrites the pre-allocated siginfo before sending the signal. Most of the written info is the same all the time, but memset(0) is very wrong. If ->sigq is queued we can race with collect_signal() which can fail to find this siginfo looking at .si_signo, or copy_siginfo() can copy the wrong .si_code/si_tid/etc.

In short, sys_timer_settime() can in fact stop the active timer, or the user can receive the siginfo with the wrong .si_xxx values.

Move "memset(->info, 0)" from posix_timer_event() to alloc_posix_timer(), change send_sigqueue() to set .si_overrun = 0 when ->sigq is not queued. It would be nice to move the whole sigq->info initialization from send to create path, but this is not easy to do without uglifying timer_create() further.

As Roland rightly pointed out, we need more cleanups/fixes here, see the "FIXME" comment in the patch. Hopefully this patch makes sense anyway, and it can mask the most bad implications.

---
 kernel/posix-timers.c |   17 +++++++++++++----
 kernel/signal.c       |    1 +
 2 files changed, 14 insertions(+), 4 deletions(-)
kernel/posix-timers.c +13 -4
@@ -296,14 +296,22 @@ void do_schedule_next_timer(struct sigin
 		unlock_timer(timr, flags);
 }
 
-int posix_timer_event(struct k_itimer *timr,int si_private)
+int posix_timer_event(struct k_itimer *timr, int si_private)
 {
-	memset(&timr->sigq->info, 0, sizeof(siginfo_t));
+	/*
+	 * FIXME: if ->sigq is queued we can race with
+	 * dequeue_signal()->do_schedule_next_timer().
+	 *
+	 * If dequeue_signal() sees the "right" value of
+	 * si_sys_private it calls do_schedule_next_timer().
+	 * We re-queue ->sigq and drop ->it_lock().
+	 * do_schedule_next_timer() locks the timer
+	 * and re-schedules it while ->sigq is pending.
+	 * Not really bad, but not that we want.
+	 */
 	timr->sigq->info.si_sys_private = si_private;
-	/* Send signal to the process that owns this timer.*/
 
 	timr->sigq->info.si_signo = timr->it_sigev_signo;
-	timr->sigq->info.si_errno = 0;
 	timr->sigq->info.si_code = SI_TIMER;
 	timr->sigq->info.si_tid = timr->it_id;
 	timr->sigq->info.si_value = timr->it_sigev_value;
@@ -435,6 +443,7 @@ static struct k_itimer * alloc_posix_tim
 		kmem_cache_free(posix_timers_cache, tmr);
 		tmr = NULL;
 	}
+	memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
 	return tmr;
 }
 
kernel/signal.c +1 -0
@@ -1319,6 +1319,7 @@ int send_sigqueue(struct sigqueue *q, st
 		q->info.si_overrun++;
 		goto out;
 	}
+	q->info.si_overrun = 0;
 
 	signalfd_notify(t, sig);
 	pending = group ? &t->signal->shared_pending : &t->pending;
author
#11 lore raw

PATCH 11/60 radeonfb: fix accel engine hangs

In reply to Greg KH

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

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

commit 969830b2fedf8336c41d6195f49d250b1e166ff8 upstream

Some chips appear to have the 2D engine hang during screen redraw, typically in a sequence of copyarea operations. This appear to be solved by adding a flush of the engine destination pixel cache and waiting for the engine to be idle before issuing the accel operation. The performance impact seems to be fairly small.

Here is a trace on an RV370 (PCI device ID 0x5b64), it records the RBBM_STATUS register, then the source x/y, destination x/y, and width/height used for the copy:

----------------------------------------
radeonfb_prim_copyarea: STATUS[00000140] src[210:70] dst[210:60] wh[a0:10]
radeonfb_prim_copyarea: STATUS[00000140] src[2b8:70] dst[2b8:60] wh[88:10]
radeonfb_prim_copyarea: STATUS[00000140] src[348:70] dst[348:60] wh[40:10]
radeonfb_prim_copyarea: STATUS[80020140] src[390:70] dst[390:60] wh[88:10]
radeonfb_prim_copyarea: STATUS[8002613f] src[40:80] dst[40:70] wh[28:10]
radeonfb_prim_copyarea: STATUS[80026139] src[a8:80] dst[a8:70] wh[38:10]
radeonfb_prim_copyarea: STATUS[80026133] src[e8:80] dst[e8:70] wh[80:10]
radeonfb_prim_copyarea: STATUS[8002612d] src[170:80] dst[170:70] wh[30:10]
radeonfb_prim_copyarea: STATUS[80026127] src[1a8:80] dst[1a8:70] wh[8:10]
radeonfb_prim_copyarea: STATUS[80026121] src[1b8:80] dst[1b8:70] wh[88:10]
radeonfb_prim_copyarea: STATUS[8002611b] src[248:80] dst[248:70] wh[68:10]
----------------------------------------

When things are going fine the copies complete before the next ROP is even issued, but all of a sudden the 2D unit becomes active (bit 17 in RBBM_STATUS) and the FIFO retry (bit 13) and FIFO pipeline busy (bit
14) are set as well. The FIFO begins to backup until it becomes full.

What happens next is the radeon_fifo_wait() times out, and we access the chip illegally leading to a bus error which usually wedges the box. None of this makes it to the console screen, of course :-) radeon_fifo_wait() should be modified to reset the accelerator when this timeout happens instead of programming the chip anyways.

----------------------------------------
radeonfb: FIFO Timeout !
ERROR(0): Cheetah error trap taken afsr[0010080005000000] afar[000007f900800e40] TL1(0)
ERROR(0): TPC[595114] TNPC[595118] O7[459788] TSTATE[11009601]
ERROR(0): TPC<radeonfb_copyarea+0xfc/0x248>
ERROR(0): M_SYND(0), E_SYND(0), Privileged
ERROR(0): Highest priority error (0000080000000000) "Bus error response from system bus"
ERROR(0): D-cache idx[0] tag[0000000000000000] utag[0000000000000000] stag[0000000000000000] ERROR(0): D-cache data0[0000000000000000] data1[0000000000000000] data2[0000000000000000] data3[0000000000000000] ERROR(0): I-cache idx[0] tag[0000000000000000] utag[0000000000000000] stag[0000000000000000] u[0000000000000000] l[00\

ERROR(0): I-cache INSN0[0000000000000000] INSN1[0000000000000000] INSN2[0000000000000000] INSN3[0000000000000000] ERROR(0): I-cache INSN4[0000000000000000] INSN5[0000000000000000] INSN6[0000000000000000] INSN7[0000000000000000] ERROR(0): E-cache idx[800e40] tag[000000000e049f4c]
ERROR(0): E-cache data0[fffff8127d300180] data1[00000000004b5384] data2[0000000000000000] data3[0000000000000000] Ker:xnel panic - not syncing: Irrecoverable deferred error trap.
----------------------------------------

Another quirk is that these copyarea calls will not happen until the first drivers/char/vt.c:redraw_screen() occurs. This will only happen if you 1) VC switch or 2) run "consolechars" or 3) unblank the screen.

This seems to happen because until a redraw_screen() the screen scrolling method used by fbcon is not finalized yet. I've seen this with other fb drivers too.

So if all you do is boot straight into X you will never see this bug on the relevant chips.

---
 drivers/video/aty/radeon_accel.c |    8 ++++++++
 include/video/radeon.h           |    4 ++++
 2 files changed, 12 insertions(+)
drivers/video/aty/radeon_accel.c +8 -0
@@ -55,6 +55,10 @@ static void radeonfb_prim_fillrect(struc
 	OUTREG(DP_WRITE_MSK, 0xffffffff);
 	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
 
+	radeon_fifo_wait(2);
+	OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+	OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+
 	radeon_fifo_wait(2);  
 	OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
 	OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
@@ -116,6 +120,10 @@ static void radeonfb_prim_copyarea(struc
 	OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
 			| (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
 
+	radeon_fifo_wait(2);
+	OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+	OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+
 	radeon_fifo_wait(3);
 	OUTREG(SRC_Y_X, (sy << 16) | sx);
 	OUTREG(DST_Y_X, (dy << 16) | dx);
include/video/radeon.h +4 -0
@@ -741,6 +741,10 @@
 #define SOFT_RESET_RB           		   (1 <<  6)
 #define SOFT_RESET_HDP          		   (1 <<  7)
 
+/* WAIT_UNTIL bit constants */
+#define WAIT_DMA_GUI_IDLE			   (1 << 9)
+#define WAIT_2D_IDLECLEAN			   (1 << 16)
+
 /* SURFACE_CNTL bit consants */
 #define SURF_TRANSLATION_DIS			   (1 << 8)
 #define NONSURF_AP0_SWP_16BPP			   (1 << 20)
author
#12 lore raw

PATCH 12/60 matrox maven: fix a broken error path

In reply to Greg KH

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

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

commit 5ede40f87957c6ededf9284c8339722a97b9dfb6 upstream

I broke an error path with d03c21ec0be7787ff6b75dcf56c0e96209ccbfbd, sorry about that.

The machine will crash if the i2c_attach_client() or maven_init_client() calls fail, although nobody has yet reported this happening.

---
 drivers/video/matrox/matroxfb_maven.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/matrox/matroxfb_maven.c +1 -1
@@ -1266,7 +1266,7 @@ static int maven_detect_client(struct i2
 ERROR4:;
 	i2c_detach_client(new_client);
 ERROR3:;
-	kfree(new_client);
+	kfree(data);
 ERROR0:;
 	return err;
 }
author
#13 lore raw

PATCH 13/60 USB: pl2023: Remove USB id (4348:5523) handled by ch341

In reply to Greg KH

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

------------------
From: Tollef Fog Heen <[email protected]>

commit 8c809681ba0289afd0ed7bbb63679a0568dd441d upstream

USB ID 4348:5523 is handled by the ch341 driver. Remove it from the pl2023 driver.

Reverts 002e8f2c80c6be76bb312940bc278fc10b2b2487.

---
 drivers/usb/serial/pl2303.c |    1 -
 drivers/usb/serial/pl2303.h |    4 ----
 2 files changed, 5 deletions(-)
drivers/usb/serial/pl2303.c +0 -1
@@ -89,7 +89,6 @@ static struct usb_device_id id_table [] 
 	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
 	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
 	{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
-	{ USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
 	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
drivers/usb/serial/pl2303.h +0 -4
@@ -107,10 +107,6 @@
 #define COREGA_VENDOR_ID	0x07aa
 #define COREGA_PRODUCT_ID	0x002a
 
-/* HL HL-340 (ID: 4348:5523) */
-#define HL340_VENDOR_ID		0x4348
-#define HL340_PRODUCT_ID	0x5523
-
 /* Y.C. Cable U.S.A., Inc - USB to RS-232 */
 #define YCCABLE_VENDOR_ID	0x05ad
 #define YCCABLE_PRODUCT_ID	0x0fba
author
#14 lore raw

PATCH 14/60 USB: fix interface unregistration logic

In reply to Greg KH

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

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

commit 1a21175a615ed346e8043f5e9d60a672266b84b4 upstream

This patch (as1122) fixes a bug: When an interface is unregistered, its children (sysfs files and endpoint devices) are unregistered after it instead of before.

---
 drivers/usb/core/message.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/core/message.c +1 -1
@@ -1091,8 +1091,8 @@ void usb_disable_device(struct usb_devic
 				continue;
 			dev_dbg(&dev->dev, "unregistering interface %s\n",
 				interface->dev.bus_id);
-			device_del(&interface->dev);
 			usb_remove_sysfs_intf_files(interface);
+			device_del(&interface->dev);
 		}
 
 		/* Now that the interfaces are unbound, nobody should
author
#15 lore raw

PATCH 15/60 usb-storage: unusual_devs entries for iRiver T10 and Datafab CF+SM reader

In reply to Greg KH

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

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

commit 368ee6469c327364ea10082a348f91c1f5ba47f7 upstream

This patch (as1115) adds unusual_devs entries with the IGNORE_RESIDE flag for the iRiver T10 and the Simple Tech/Datafab CF+SM card reader. Apparently these devices provide reasonable residue values for READ and WRITE operations, but not for others like INQUIRY or READ CAPACITY.

This fixes the iRiver T10 problem reported in Bugzilla #11125.

---
 drivers/usb/storage/unusual_devs.h |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/usb/storage/unusual_devs.h +14 -0
@@ -1187,6 +1187,13 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
+/* Reported by Rauch Wolke <[email protected]> */
+UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
+		"Simple Tech/Datafab",
+		"CF+SM Reader",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
  * to the USB storage specification in two ways:
  * - They tell us they are using transport protocol CBI. In reality they
@@ -1758,6 +1765,13 @@ UNUSUAL_DEV(  0x2770, 0x915d, 0x0010, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY ),
 
+/* Reported by Andrey Rahmatullin <[email protected]> */
+UNUSUAL_DEV(  0x4102, 0x1020, 0x0100,  0x0100,
+		"iRiver",
+		"MP3 T10",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /*
  * David Härdeman <[email protected]>
  * The key makes the SCSI stack print confusing (but harmless) messages
author
#16 lore raw

PATCH 16/60 USB: usb-storage: quirk around v1.11 firmware on Nikon D4

In reply to Greg KH

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

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

commit b9a097f26e55968cbc52e30a4a2e73d32d7604ce upstream

usb-storage: quirk around v1.11 firmware on Nikon D40

https://bugzilla.redhat.com/show_bug.cgi?id=454028
Just as in earlier firmware versions, we need to perform this quirk for the latest version too.

Speculatively do the entry for the D80 too, as they seem to have the same firmware problems historically.

---
 drivers/usb/storage/unusual_devs.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/storage/unusual_devs.h +2 -2
@@ -358,14 +358,14 @@ UNUSUAL_DEV(  0x04b0, 0x040f, 0x0100, 0x
 		US_FL_FIX_CAPACITY),
 
 /* Reported by Emil Larsson <[email protected]> */
-UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0110,
+UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0111,
 		"NIKON",
 		"NIKON DSC D80",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
 /* Reported by Ortwin Glueck <[email protected]> */
-UNUSUAL_DEV(  0x04b0, 0x0413, 0x0110, 0x0110,
+UNUSUAL_DEV(  0x04b0, 0x0413, 0x0110, 0x0111,
 		"NIKON",
 		"NIKON DSC D40",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
author
#17 lore raw

PATCH 17/60 usb-serial: dont release unregistered minors

In reply to Greg KH

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

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

commit 0282b7f2a874e72c18fcd5a112ccf67f71ba7f5c upstream

This patch (as1121) fixes a bug in the USB serial core. When a device is unregistered, the core will give back its minors -- even if the device hasn't been assigned any!

The patch reserves the highest minor value (255) to mean that no minor was assigned. It also removes some dead code and does a small style fixup.

---
 drivers/usb/serial/usb-serial.c |    7 +++----
 include/linux/usb/serial.h      |    3 ++-
 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/usb/serial/usb-serial.c +3 -4
@@ -119,9 +119,6 @@ static void return_serial(struct usb_ser
 
 	dbg("%s", __func__);
 
-	if (serial == NULL)
-		return;
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		serial_table[serial->minor + i] = NULL;
 	}
@@ -140,7 +137,8 @@ static void destroy_serial(struct kref *
 	serial->type->shutdown(serial);
 
 	/* return the minor range that this device had */
-	return_serial(serial);
+	if (serial->minor != SERIAL_TTY_NO_MINOR)
+		return_serial(serial);
 
 	for (i = 0; i < serial->num_ports; ++i)
 		serial->port[i]->open_count = 0;
@@ -562,6 +560,7 @@ static struct usb_serial * create_serial
 	serial->interface = interface;
 	kref_init(&serial->kref);
 	mutex_init(&serial->disc_mutex);
+	serial->minor = SERIAL_TTY_NO_MINOR;
 
 	return serial;
 }
include/linux/usb/serial.h +2 -1
@@ -17,7 +17,8 @@
 #include <linux/mutex.h>
 
 #define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
-#define SERIAL_TTY_MINORS	255	/* loads of devices :) */
+#define SERIAL_TTY_MINORS	254	/* loads of devices :) */
+#define SERIAL_TTY_NO_MINOR	255	/* No minor was assigned */
 
 /* The maximum number of ports one device can grab at once */
 #define MAX_NUM_PORTS		8
author
#18 lore raw

PATCH 18/60 USB: ftdi_sio: add support for Luminance Stellaris Evaluation/Development Kits

In reply to Greg KH

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

------------------
From: Frederik Kriewitz <[email protected]>

commit a00c3cadc2bf50b3c925acdb3d0e5789b1650498 upstream

The Patch adds support for Luminance Stellaris Evaluation/Development Kits (FTDI 2232C based).
The PIDs were missing.

Successfully tested with a Stellaris LM3S8962 Evaluation kit.

---
 drivers/usb/serial/ftdi_sio.c |    4 ++++
 drivers/usb/serial/ftdi_sio.h |    5 +++++
 2 files changed, 9 insertions(+)
drivers/usb/serial/ftdi_sio.c +4 -0
@@ -636,6 +636,10 @@ static struct usb_device_id id_table_com
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
 	{ USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) },
 	{ },					/* Optional parameter entry */
drivers/usb/serial/ftdi_sio.h +5 -0
@@ -815,6 +815,11 @@
 #define OLIMEX_VID			0x15BA
 #define OLIMEX_ARM_USB_OCD_PID		0x0003
 
+/* Luminary Micro Stellaris Boards, VID = FTDI_VID */
+/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
+#define LMI_LM3S_DEVEL_BOARD_PID	0xbcd8
+#define LMI_LM3S_EVAL_BOARD_PID		0xbcd9
+
 /* www.elsterelectricity.com Elster Unicom III Optical Probe */
 #define FTDI_ELSTER_UNICOM_PID		0xE700 /* Product Id */
 
author
#19 lore raw

PATCH 19/60 USB: ftdi_sio: Add USB Product Id for ELV HS485

In reply to Greg KH

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

------------------
From: Andre Schenk <[email protected]>

commit b5894a500127fce1db1309db5f9ca8b77a2ac266 upstream

USB product id registration for the ELV HS485 USB adapter (www.elv.de) to their home automation bus system. Applies to 2.6.26.

---
 drivers/usb/serial/ftdi_sio.c |    1 +
 drivers/usb/serial/ftdi_sio.h |    1 +
 2 files changed, 2 insertions(+)
drivers/usb/serial/ftdi_sio.c +1 -0
@@ -553,6 +553,7 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
drivers/usb/serial/ftdi_sio.h +1 -0
@@ -524,6 +524,7 @@
 #define FTDI_ELV_WS300PC_PID	0xE0F6	/* PC-Wetterstation (WS 300 PC) */
 #define FTDI_ELV_FHZ1300PC_PID	0xE0E8	/* FHZ 1300 PC */
 #define FTDI_ELV_WS500_PID	0xE0E9	/* PC-Wetterstation (WS 500) */
+#define FTDI_ELV_HS485_PID	0xE0EA	/* USB to RS-485 adapter */
 #define FTDI_ELV_EM1010PC_PID	0xE0EF	/* Engery monitor EM 1010 PC */
 
 /*
author
#20 lore raw

PATCH 20/60 ipvs: Fix possible deadlock in estimator code

In reply to Greg KH

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

------------------
From: Sven Wegener <[email protected]>

commit 8ab19ea36c5c5340ff598e4d15fc084eb65671dc upstream

There is a slight chance for a deadlock in the estimator code. We can't call del_timer_sync() while holding our lock, as the timer might be active and spinning for the lock on another cpu. Work around this issue by using try_to_del_timer_sync() and releasing the lock. We could actually delete the timer outside of our lock, as the add and kill functions are only every called from userspace via [gs]etsockopt() and are serialized by a mutex, but better make this explicit.

---
 net/ipv4/ipvs/ip_vs_est.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
net/ipv4/ipvs/ip_vs_est.c +5 -2
@@ -172,8 +172,11 @@ void ip_vs_kill_estimator(struct ip_vs_s
 		kfree(est);
 		killed++;
 	}
-	if (killed && est_list == NULL)
-		del_timer_sync(&est_timer);
+	while (killed && !est_list && try_to_del_timer_sync(&est_timer) < 0) {
+		write_unlock_bh(&est_lock);
+		cpu_relax();
+		write_lock_bh(&est_lock);
+	}
 	write_unlock_bh(&est_lock);
 }
 
author
#21 lore raw

PATCH 21/60 acer-wmi: Fix wireless and bluetooth on early AMW0 v2 laptops

In reply to Greg KH

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

------------------
From: Carlos Corbacho <[email protected]>

commit 5c742b45dd5fbbb6cf74d3378341704f4b23c5e8 upstream

In the old acer_acpi, I discovered that on some of the newer AMW0 laptops that supported the WMID methods, they don't work properly for setting the wireless and bluetooth values.

So for the AMW0 V2 laptops, we want to use both the 'old' AMW0 and the 'new' WMID methods for setting wireless & bluetooth to guarantee we always enable it.

This was fixed in acer_acpi some time ago, but I forgot to port the patch over to acer-wmi when it was merged.

(Without this patch, early AMW0 V2 laptops such as the Aspire 5040 won't work with acer-wmi, where-as they did with the old acer_acpi).

AK: fix compilation

---
 drivers/misc/acer-wmi.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/misc/acer-wmi.c +19 -0
@@ -742,11 +742,30 @@ static acpi_status get_u32(u32 *value, u
 
 static acpi_status set_u32(u32 value, u32 cap)
 {
+	acpi_status status;
+
 	if (interface->capability & cap) {
 		switch (interface->type) {
 		case ACER_AMW0:
 			return AMW0_set_u32(value, cap, interface);
 		case ACER_AMW0_V2:
+			if (cap == ACER_CAP_MAILLED)
+				return AMW0_set_u32(value, cap, interface);
+
+			/*
+			 * On some models, some WMID methods don't toggle
+			 * properly. For those cases, we want to run the AMW0
+			 * method afterwards to be certain we've really toggled
+			 * the device state.
+			 */
+			if (cap == ACER_CAP_WIRELESS ||
+				cap == ACER_CAP_BLUETOOTH) {
+				status = WMID_set_u32(value, cap, interface);
+				if (ACPI_FAILURE(status))
+					return status;
+
+				return AMW0_set_u32(value, cap, interface);
+			}
 		case ACER_WMID:
 			return WMID_set_u32(value, cap, interface);
 		default:
author
#22 lore raw

PATCH 22/60 CIFS: mount of IPC$ breaks with iget patch

In reply to Greg KH

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

------------------
From: Steve French <[email protected]>

commit ad661334b8ae421154b121ee6ad3b56807adbf11 upstream

In looking at network named pipe support on cifs, I noticed that Dave Howell's iget patch:

iget: stop CIFS from using iget() and read_inode()

broke mounts to IPC$ (the interprocess communication share), and don't handle the error case (when getting info on the root inode fails).

Thanks to Gunter who noted a typo in a debug line in the original version of this patch.

---
 fs/cifs/inode.c |    1 +
 1 file changed, 1 insertion(+)
fs/cifs/inode.c +1 -0
@@ -649,6 +649,7 @@ struct inode *cifs_iget(struct super_blo
 		inode->i_fop = &simple_dir_operations;
 		inode->i_uid = cifs_sb->mnt_uid;
 		inode->i_gid = cifs_sb->mnt_gid;
+	} else if (rc) {
 		_FreeXid(xid);
 		iget_failed(inode);
 		return ERR_PTR(rc);
author
#23 lore raw

PATCH 23/60 CIFS: if get root inode fails during mount, cleanup tree connection

In reply to Greg KH

From: Steve French <[email protected]>

commit 2c731afb0d4ba16018b400c75665fbdb8feb2175 upstream

---
 fs/cifs/cifsfs.c |    2 ++
 1 file changed, 2 insertions(+)
fs/cifs/cifsfs.c +2 -0
@@ -175,6 +175,8 @@ out_no_root:
 	if (inode)
 		iput(inode);
 
+	cifs_umount(sb, cifs_sb);
+
 out_mount_failed:
 	if (cifs_sb) {
 #ifdef CONFIG_CIFS_DFS_UPCALL
author
#24 lore raw

PATCH 24/60 dccp: change L/R must have at least one byte in the dccpsf_val field

In reply to Greg KH

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

------------------
From: Arnaldo Carvalho de Melo <[email protected]>

commit 3e8a0a559c66ee9e7468195691a56fefc3589740 upstream

Thanks to Eugene Teo for reporting this problem.

---
 net/dccp/proto.c |    5 +++++
 1 file changed, 5 insertions(+)
net/dccp/proto.c +5 -0
@@ -476,6 +476,11 @@ static int dccp_setsockopt_change(struct
 
 	if (copy_from_user(&opt, optval, sizeof(opt)))
 		return -EFAULT;
+	/*
+	 * rfc4340: 6.1. Change Options
+	 */
+	if (opt.dccpsf_len < 1)
+		return -EINVAL;
 
 	val = kmalloc(opt.dccpsf_len, GFP_KERNEL);
 	if (!val)
author
#25 lore raw

PATCH 25/60 syncookies: Make sure ECN is disabled

In reply to Greg KH

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

------------------
From: Florian Westphal <[email protected]>

[ Upstream commit 16df845f4566bc252f3e09db12f5c2f22cb44226 ]

ecn_ok is not initialized when a connection is established by cookies. The cookie syn-ack never sets ECN, so ecn_ok must be set to 0.

Spotted using ns-3/network simulation cradle simulator and valgrind.

---
 net/ipv4/syncookies.c |    1 +
 net/ipv6/syncookies.c |    1 +
 2 files changed, 2 insertions(+)
net/ipv4/syncookies.c +1 -0
@@ -301,6 +301,7 @@ struct sock *cookie_v4_check(struct sock
 	ireq->rmt_port		= th->source;
 	ireq->loc_addr		= ip_hdr(skb)->daddr;
 	ireq->rmt_addr		= ip_hdr(skb)->saddr;
+	ireq->ecn_ok		= 0;
 	ireq->snd_wscale	= tcp_opt.snd_wscale;
 	ireq->rcv_wscale	= tcp_opt.rcv_wscale;
 	ireq->sack_ok		= tcp_opt.sack_ok;
net/ipv6/syncookies.c +1 -0
@@ -223,6 +223,7 @@ struct sock *cookie_v6_check(struct sock
 
 	req->expires = 0UL;
 	req->retrans = 0;
+	ireq->ecn_ok		= 0;
 	ireq->snd_wscale	= tcp_opt.snd_wscale;
 	ireq->rcv_wscale	= tcp_opt.rcv_wscale;
 	ireq->sack_ok		= tcp_opt.sack_ok;
author
#26 lore raw

PATCH 26/60 random32: seeding improvement

In reply to Greg KH

From: Stephen Hemminger <[email protected]>

[ Upstream commit 697f8d0348a652593d195a13dd1067d9df911a82 ]

The rationale is:
* use u32 consistently
* no need to do LCG on values from (better) get_random_bytes
* use more data from get_random_bytes for secondary seeding
* don't reduce state space on srandom32()
* enforce state variable initialization restrictions

Note: the second paper has a version of random32() with even longer period and a version of random64() if needed.

---
 lib/random32.c |   48 +++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)
lib/random32.c +27 -21
@@ -56,23 +56,12 @@ static u32 __random32(struct rnd_state *
 	return (state->s1 ^ state->s2 ^ state->s3);
 }
 
-static void __set_random32(struct rnd_state *state, unsigned long s)
+/*
+ * Handle minimum values for seeds
+ */
+static inline u32 __seed(u32 x, u32 m)
 {
-	if (s == 0)
-		s = 1;      /* default seed is 1 */
-
-#define LCG(n) (69069 * n)
-	state->s1 = LCG(s);
-	state->s2 = LCG(state->s1);
-	state->s3 = LCG(state->s2);
-
-	/* "warm it up" */
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
+	return (x < m) ? x + m : x;
 }
 
 /**
@@ -107,7 +96,7 @@ void srandom32(u32 entropy)
 	 */
 	for_each_possible_cpu (i) {
 		struct rnd_state *state = &per_cpu(net_rand_state, i);
-		__set_random32(state, state->s1 ^ entropy);
+		state->s1 = __seed(state->s1 ^ entropy, 1);
 	}
 }
 EXPORT_SYMBOL(srandom32);
@@ -122,7 +111,19 @@ static int __init random32_init(void)
 
 	for_each_possible_cpu(i) {
 		struct rnd_state *state = &per_cpu(net_rand_state,i);
-		__set_random32(state, i + jiffies);
+
+#define LCG(x)	((x) * 69069)	/* super-duper LCG */
+		state->s1 = __seed(LCG(i + jiffies), 1);
+		state->s2 = __seed(LCG(state->s1), 7);
+		state->s3 = __seed(LCG(state->s2), 15);
+
+		/* "warm it up" */
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
 	}
 	return 0;
 }
@@ -135,13 +136,18 @@ core_initcall(random32_init);
 static int __init random32_reseed(void)
 {
 	int i;
-	unsigned long seed;
 
 	for_each_possible_cpu(i) {
 		struct rnd_state *state = &per_cpu(net_rand_state,i);
+		u32 seeds[3];
+
+		get_random_bytes(&seeds, sizeof(seeds));
+		state->s1 = __seed(seeds[0], 1);
+		state->s2 = __seed(seeds[1], 7);
+		state->s3 = __seed(seeds[2], 15);
 
-		get_random_bytes(&seed, sizeof(seed));
-		__set_random32(state, seed);
+		/* mix it in */
+		__random32(state);
 	}
 	return 0;
 }
author
#27 lore raw

PATCH 27/60 ipv6: Fix ip6_xmit to send fragments if ipfragok is true

In reply to Greg KH

From: Wei Yongjun <[email protected]>

[ Upstream commit 77e2f14f71d68d05945f1d30ca55b5194d6ab1ce ]

SCTP used ip6_xmit() to send fragments after received ICMP packet too big message. But while send packet used ip6_xmit, the skb->local_df is not initialized. So when skb if enter ip6_fragment(), the following code will discard the skb.

ip6_fragment(...)

{
    if (!skb->local_df) {
        ...
        return -EMSGSIZE;
    }
    ...
}

SCTP do the following step:
1. send packet ip6_xmit(skb, ipfragok=0)
2. received ICMP packet too big message
3. if PMTUD_ENABLE: ip6_xmit(skb, ipfragok=1)

This patch fixed the problem by set local_df if ipfragok is true.

---
 net/ipv6/ip6_output.c |    4 ++++
 1 file changed, 4 insertions(+)
net/ipv6/ip6_output.c +4 -0
@@ -231,6 +231,10 @@ int ip6_xmit(struct sock *sk, struct sk_
 	skb_reset_network_header(skb);
 	hdr = ipv6_hdr(skb);
 
+	/* Allow local fragmentation. */
+	if (ipfragok)
+		skb->local_df = 1;
+
 	/*
 	 *	Fill in the IPv6 header
 	 */
author
#28 lore raw

PATCH 28/60 sparc64: FUTEX_OP_ANDN fix

In reply to Greg KH

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

------------------
From: Mikael Pettersson <[email protected]>

[ Upstream commit d72609e17fd93bb2f7e0f7e1bdc70b6d20e43843 ]

Correct sparc64's implementation of FUTEX_OP_ANDN to do a bitwise negate of the oparg parameter before applying the AND operation. All other archs that support FUTEX_OP_ANDN either negate oparg explicitly (frv, ia64, mips, sh, x86), or do so indirectly by using an and-not instruction (powerpc). Since sparc64 has and-not, I chose to use that solution.

I've not found any use of FUTEX_OP_ANDN in glibc so the impact of this bug is probably minor. But other user-space components may try to use it so it should still get fixed.

---
 include/asm-sparc64/futex.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-sparc64/futex.h +1 -1
@@ -59,7 +59,7 @@ static inline int futex_atomic_op_inuser
 		__futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
+		__futex_cas_op("andn\t%2, %4, %1", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_XOR:
 		__futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
author
#29 lore raw

PATCH 29/60 sparc64: Fix global reg snapshotting on self-cpu.

In reply to Greg KH

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

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

[ Upstream commit 17b6f586b8e27914b36c9ed7f3e4d289e6274a80 ]

We were picking %i7 out of the wrong register window stack slot.

---
 arch/sparc64/kernel/process.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sparc64/kernel/process.c +1 -1
@@ -320,7 +320,7 @@ static void __global_reg_self(struct thr
 
 		rw = (struct reg_window *)
 			(regs->u_regs[UREG_FP] + STACK_BIAS);
-		global_reg_snapshot[this_cpu].i7 = rw->ins[6];
+		global_reg_snapshot[this_cpu].i7 = rw->ins[7];
 	} else
 		global_reg_snapshot[this_cpu].i7 = 0;
 
author
#30 lore raw

PATCH 30/60 sparc64: Do not clobber %g7 in setcontext() trap.

In reply to Greg KH

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

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

[ Upstream commit 0a4949c4414af2eb91414bcd8e2a8ac3706f7dde ]

That's the userland thread register, so we should never try to change it like this.

Based upon glibc bug nptl/6577 and suggestions by Jakub Jelinek.

---
 arch/sparc64/kernel/signal.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/sparc64/kernel/signal.c +4 -2
@@ -2,7 +2,7 @@
  *  arch/sparc64/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1995 David S. Miller ([email protected])
+ *  Copyright (C) 1995, 2008 David S. Miller ([email protected])
  *  Copyright (C) 1996 Miguel de Icaza ([email protected])
  *  Copyright (C) 1997 Eddie C. Dost   ([email protected])
  *  Copyright (C) 1997,1998 Jakub Jelinek   ([email protected])
@@ -89,7 +89,9 @@ asmlinkage void sparc64_set_context(stru
 	err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
 	err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
 	err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
-	err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7]));
+
+	/* Skip %g7 as that's the thread register in userspace.  */
+
 	err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
 	err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
 	err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
author
#31 lore raw

PATCH 31/60 KVM: task switch: segment base is linear address

In reply to Greg KH

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

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

From: Marcelo Tosatti <[email protected]>

(cherry picked from commit 98899aa0e0bf5de05850082be0eb837058c09ea5)

The segment base is always a linear address, so translate before accessing guest memory.

---
 arch/x86/kvm/x86.c |   12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
arch/x86/kvm/x86.c +9 -3
@@ -3207,6 +3207,7 @@ static void get_segment_descritptor_dtab
 static int load_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 					 struct desc_struct *seg_desc)
 {
+	gpa_t gpa;
 	struct descriptor_table dtable;
 	u16 index = selector >> 3;
 
@@ -3216,13 +3217,16 @@ static int load_guest_segment_descriptor
 		kvm_queue_exception_e(vcpu, GP_VECTOR, selector & 0xfffc);
 		return 1;
 	}
-	return kvm_read_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
+	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
+	gpa += index * 8;
+	return kvm_read_guest(vcpu->kvm, gpa, seg_desc, 8);
 }
 
 /* allowed just for 8 bytes segments */
 static int save_guest_segment_descriptor(struct kvm_vcpu *vcpu, u16 selector,
 					 struct desc_struct *seg_desc)
 {
+	gpa_t gpa;
 	struct descriptor_table dtable;
 	u16 index = selector >> 3;
 
@@ -3230,7 +3234,9 @@ static int save_guest_segment_descriptor
 
 	if (dtable.limit < index * 8 + 7)
 		return 1;
-	return kvm_write_guest(vcpu->kvm, dtable.base + index * 8, seg_desc, 8);
+	gpa = vcpu->arch.mmu.gva_to_gpa(vcpu, dtable.base);
+	gpa += index * 8;
+	return kvm_write_guest(vcpu->kvm, gpa, seg_desc, 8);
 }
 
 static u32 get_tss_base_addr(struct kvm_vcpu *vcpu,
@@ -3242,7 +3248,7 @@ static u32 get_tss_base_addr(struct kvm_
 	base_addr |= (seg_desc->base1 << 16);
 	base_addr |= (seg_desc->base2 << 24);
 
-	return base_addr;
+	return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
 }
 
 static int load_tss_segment32(struct kvm_vcpu *vcpu,
author
#32 lore raw

PATCH 32/60 KVM: task switch: use seg regs provided by subarch instead of reading from GDT

In reply to Greg KH

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

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

From: Marcelo Tosatti <[email protected]>

(cherry-picked from commit 34198bf8426276a2ce1e97056a0f02d43637e5ae)

There is no guarantee that the old TSS descriptor in the GDT contains the proper base address. This is the case for Windows installation's reboot-via-triplefault.

Use guest registers instead. Also translate the address properly.

---
 arch/x86/kvm/x86.c |   93 +++++++++++++++++------------------------------------
 1 file changed, 30 insertions(+), 63 deletions(-)
arch/x86/kvm/x86.c +30 -63
@@ -3251,54 +3251,6 @@ static u32 get_tss_base_addr(struct kvm_
 	return vcpu->arch.mmu.gva_to_gpa(vcpu, base_addr);
 }
 
-static int load_tss_segment32(struct kvm_vcpu *vcpu,
-			      struct desc_struct *seg_desc,
-			      struct tss_segment_32 *tss)
-{
-	u32 base_addr;
-
-	base_addr = get_tss_base_addr(vcpu, seg_desc);
-
-	return kvm_read_guest(vcpu->kvm, base_addr, tss,
-			      sizeof(struct tss_segment_32));
-}
-
-static int save_tss_segment32(struct kvm_vcpu *vcpu,
-			      struct desc_struct *seg_desc,
-			      struct tss_segment_32 *tss)
-{
-	u32 base_addr;
-
-	base_addr = get_tss_base_addr(vcpu, seg_desc);
-
-	return kvm_write_guest(vcpu->kvm, base_addr, tss,
-			       sizeof(struct tss_segment_32));
-}
-
-static int load_tss_segment16(struct kvm_vcpu *vcpu,
-			      struct desc_struct *seg_desc,
-			      struct tss_segment_16 *tss)
-{
-	u32 base_addr;
-
-	base_addr = get_tss_base_addr(vcpu, seg_desc);
-
-	return kvm_read_guest(vcpu->kvm, base_addr, tss,
-			      sizeof(struct tss_segment_16));
-}
-
-static int save_tss_segment16(struct kvm_vcpu *vcpu,
-			      struct desc_struct *seg_desc,
-			      struct tss_segment_16 *tss)
-{
-	u32 base_addr;
-
-	base_addr = get_tss_base_addr(vcpu, seg_desc);
-
-	return kvm_write_guest(vcpu->kvm, base_addr, tss,
-			       sizeof(struct tss_segment_16));
-}
-
 static u16 get_segment_selector(struct kvm_vcpu *vcpu, int seg)
 {
 	struct kvm_segment kvm_seg;
@@ -3456,20 +3408,26 @@ static int load_state_from_tss16(struct 
 }
 
 int kvm_task_switch_16(struct kvm_vcpu *vcpu, u16 tss_selector,
-		       struct desc_struct *cseg_desc,
+		       u32 old_tss_base,
 		       struct desc_struct *nseg_desc)
 {
 	struct tss_segment_16 tss_segment_16;
 	int ret = 0;
 
-	if (load_tss_segment16(vcpu, cseg_desc, &tss_segment_16))
+	if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
+			   sizeof tss_segment_16))
 		goto out;
 
 	save_state_to_tss16(vcpu, &tss_segment_16);
-	save_tss_segment16(vcpu, cseg_desc, &tss_segment_16);
 
-	if (load_tss_segment16(vcpu, nseg_desc, &tss_segment_16))
+	if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_16,
+			    sizeof tss_segment_16))
+		goto out;
+
+	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+			   &tss_segment_16, sizeof tss_segment_16))
 		goto out;
+
 	if (load_state_from_tss16(vcpu, &tss_segment_16))
 		goto out;
 
@@ -3479,20 +3437,26 @@ out:
 }
 
 int kvm_task_switch_32(struct kvm_vcpu *vcpu, u16 tss_selector,
-		       struct desc_struct *cseg_desc,
+		       u32 old_tss_base,
 		       struct desc_struct *nseg_desc)
 {
 	struct tss_segment_32 tss_segment_32;
 	int ret = 0;
 
-	if (load_tss_segment32(vcpu, cseg_desc, &tss_segment_32))
+	if (kvm_read_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
+			   sizeof tss_segment_32))
 		goto out;
 
 	save_state_to_tss32(vcpu, &tss_segment_32);
-	save_tss_segment32(vcpu, cseg_desc, &tss_segment_32);
 
-	if (load_tss_segment32(vcpu, nseg_desc, &tss_segment_32))
+	if (kvm_write_guest(vcpu->kvm, old_tss_base, &tss_segment_32,
+			    sizeof tss_segment_32))
+		goto out;
+
+	if (kvm_read_guest(vcpu->kvm, get_tss_base_addr(vcpu, nseg_desc),
+			   &tss_segment_32, sizeof tss_segment_32))
 		goto out;
+
 	if (load_state_from_tss32(vcpu, &tss_segment_32))
 		goto out;
 
@@ -3507,16 +3471,20 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 	struct desc_struct cseg_desc;
 	struct desc_struct nseg_desc;
 	int ret = 0;
+	u32 old_tss_base = get_segment_base(vcpu, VCPU_SREG_TR);
+	u16 old_tss_sel = get_segment_selector(vcpu, VCPU_SREG_TR);
 
-	get_segment(vcpu, &tr_seg, VCPU_SREG_TR);
+	old_tss_base = vcpu->arch.mmu.gva_to_gpa(vcpu, old_tss_base);
 
+	/* FIXME: Handle errors. Failure to read either TSS or their
+	 * descriptors should generate a pagefault.
+	 */
 	if (load_guest_segment_descriptor(vcpu, tss_selector, &nseg_desc))
 		goto out;
 
-	if (load_guest_segment_descriptor(vcpu, tr_seg.selector, &cseg_desc))
+	if (load_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc))
 		goto out;
 
-
 	if (reason != TASK_SWITCH_IRET) {
 		int cpl;
 
@@ -3534,8 +3502,7 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 
 	if (reason == TASK_SWITCH_IRET || reason == TASK_SWITCH_JMP) {
 		cseg_desc.type &= ~(1 << 1); //clear the B flag
-		save_guest_segment_descriptor(vcpu, tr_seg.selector,
-					      &cseg_desc);
+		save_guest_segment_descriptor(vcpu, old_tss_sel, &cseg_desc);
 	}
 
 	if (reason == TASK_SWITCH_IRET) {
@@ -3547,10 +3514,10 @@ int kvm_task_switch(struct kvm_vcpu *vcp
 	kvm_x86_ops->cache_regs(vcpu);
 
 	if (nseg_desc.type & 8)
-		ret = kvm_task_switch_32(vcpu, tss_selector, &cseg_desc,
+		ret = kvm_task_switch_32(vcpu, tss_selector, old_tss_base,
 					 &nseg_desc);
 	else
-		ret = kvm_task_switch_16(vcpu, tss_selector, &cseg_desc,
+		ret = kvm_task_switch_16(vcpu, tss_selector, old_tss_base,
 					 &nseg_desc);
 
 	if (reason == TASK_SWITCH_CALL || reason == TASK_SWITCH_GATE) {
author
#33 lore raw

PATCH 33/60 KVM: Avoid instruction emulation when event delivery is pending

In reply to Greg KH

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

------------------
From: Avi Kivity <[email protected]>

(cherry-picked from commit 577bdc496614ced56d999bbb425e85adf2386490)

When an event (such as an interrupt) is injected, and the stack is shadowed (and therefore write protected), the guest will exit. The current code will see that the stack is shadowed and emulate a few instructions, each time postponing the injection. Eventually the injection may succeed, but at that time the guest may be unwilling to accept the interrupt (for example, the TPR may have changed).

This occurs every once in a while during a Windows 2008 boot.

Fix by unshadowing the fault address if the fault was due to an event injection.

---
 arch/x86/kvm/mmu.c |    1 +
 arch/x86/kvm/svm.c |    7 ++++++-
 arch/x86/kvm/vmx.c |    2 ++
 3 files changed, 9 insertions(+), 1 deletion(-)
arch/x86/kvm/mmu.c +1 -0
@@ -1792,6 +1792,7 @@ int kvm_mmu_unprotect_page_virt(struct k
 	spin_unlock(&vcpu->kvm->mmu_lock);
 	return r;
 }
+EXPORT_SYMBOL_GPL(kvm_mmu_unprotect_page_virt);
 
 void __kvm_mmu_free_some_pages(struct kvm_vcpu *vcpu)
 {
arch/x86/kvm/svm.c +6 -1
@@ -1007,13 +1007,18 @@ static int pf_interception(struct vcpu_s
 	struct kvm *kvm = svm->vcpu.kvm;
 	u64 fault_address;
 	u32 error_code;
+	bool event_injection = false;
 
 	if (!irqchip_in_kernel(kvm) &&
-		is_external_interrupt(exit_int_info))
+	    is_external_interrupt(exit_int_info)) {
+		event_injection = true;
 		push_irq(&svm->vcpu, exit_int_info & SVM_EVTINJ_VEC_MASK);
+	}
 
 	fault_address  = svm->vmcb->control.exit_info_2;
 	error_code = svm->vmcb->control.exit_info_1;
+	if (event_injection)
+		kvm_mmu_unprotect_page_virt(&svm->vcpu, fault_address);
 	return kvm_mmu_page_fault(&svm->vcpu, fault_address, error_code);
 }
 
arch/x86/kvm/vmx.c +2 -0
@@ -2258,6 +2258,8 @@ static int handle_exception(struct kvm_v
 		cr2 = vmcs_readl(EXIT_QUALIFICATION);
 		KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2,
 			    (u32)((u64)cr2 >> 32), handler);
+		if (vect_info & VECTORING_INFO_VALID_MASK)
+			kvm_mmu_unprotect_page_virt(vcpu, cr2);
 		return kvm_mmu_page_fault(vcpu, cr2, error_code);
 	}
 
author
#34 lore raw

PATCH 34/60 KVM: task switch: translate guest segment limit to virt-extension byte granular field

In reply to Greg KH

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

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

From: Marcelo Tosatti <[email protected]>

(cherry picked from commit c93cd3a58845012df2d658fecd0ac99f7008d753)

If 'g' is one then limit is 4kb granular.

---
 arch/x86/kvm/x86.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kvm/x86.c +4 -0
@@ -3168,6 +3168,10 @@ static void seg_desct_to_kvm_desct(struc
 	kvm_desct->base |= seg_desc->base2 << 24;
 	kvm_desct->limit = seg_desc->limit0;
 	kvm_desct->limit |= seg_desc->limit << 16;
+	if (seg_desc->g) {
+		kvm_desct->limit <<= 12;
+		kvm_desct->limit |= 0xfff;
+	}
 	kvm_desct->selector = selector;
 	kvm_desct->type = seg_desc->type;
 	kvm_desct->present = seg_desc->p;
author
#35 lore raw

PATCH 35/60 KVM: ia64: Fix irq disabling leak in error handling code

In reply to Greg KH

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

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

From: Julia Lawall <[email protected]>

(cherry picked from commit cab7a1eeeb007be309cd99cf14407261a72d2418)

There is a call to local_irq_restore in the normal exit case, so it would seem that there should be one on an error return as well.

The semantic patch that finds this problem is as follows:
(http://www.emn.fr/x-info/coccinelle/)

// <smpl>
@@
expression l;
expression E,E1,E2;
@@

local_irq_save(l);
... when != local_irq_restore(l)

    when != spin_unlock_irqrestore(E,l)
    when any
    when strict
(
if (...) { ... when != local_irq_restore(l)
               when != spin_unlock_irqrestore(E1,l)
+   local_irq_restore(l);
    return ...;
}
|
if (...)
+   {local_irq_restore(l);
    return ...;

+ }
|
spin_unlock_irqrestore(E2,l);
|
local_irq_restore(l);
)
// </smpl>

---
 arch/ia64/kvm/kvm-ia64.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
arch/ia64/kvm/kvm-ia64.c +3 -2
@@ -125,9 +125,9 @@ void kvm_arch_hardware_enable(void *garb
 				PAGE_KERNEL));
 	local_irq_save(saved_psr);
 	slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+	local_irq_restore(saved_psr);
 	if (slot < 0)
 		return;
-	local_irq_restore(saved_psr);
 
 	spin_lock(&vp_lock);
 	status = ia64_pal_vp_init_env(kvm_vsa_base ?
@@ -160,9 +160,9 @@ void kvm_arch_hardware_disable(void *gar
 
 	local_irq_save(saved_psr);
 	slot = ia64_itr_entry(0x3, KVM_VMM_BASE, pte, KVM_VMM_SHIFT);
+	local_irq_restore(saved_psr);
 	if (slot < 0)
 		return;
-	local_irq_restore(saved_psr);
 
 	status = ia64_pal_vp_exit_env(host_iva);
 	if (status)
@@ -1258,6 +1258,7 @@ static int vti_vcpu_setup(struct kvm_vcp
 uninit:
 	kvm_vcpu_uninit(vcpu);
 fail:
+	local_irq_restore(psr);
 	return r;
 }
 
author
#36 lore raw

PATCH 36/60 r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06

In reply to Greg KH

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

------------------
From: Marcus Sundberg <[email protected]>

commit 77332894c21165404496c56763d7df6c15c4bb09 upstream

The magic write to register 0x82 will often cause PCI config space on my 8168 (PCI ID 10ec:8168, revision 2. mounted in an LG P300 laptop) to be filled with ones during driver load, and thus breaking NIC operation until reboot. If it does not happen on first driver load it can easily be reproduced by unloading and loading the driver a few times.

The magic write was added long ago by this commit:

Author: François Romieu <[email protected]>
Date:   Sat Jan 10 06:00:46 2004 -0500

[netdrvr r8169] Merge of changes done by Realtek to rtl8169_init_one():
- phy capability settings allows lower or equal capability as suggested in Realtek's changes;
- I/O voodoo;
- no need to s/mdio_write/RTL8169_WRITE_GMII_REG/;
- s/rtl8169_hw_PHY_config/rtl8169_hw_phy_config/;
- rtl8169_hw_phy_config(): ad-hoc struct "phy_magic" to limit duplication of code (yep, the u16 -> int conversions should work as expected);
- variable renames and whitepace changes ignored.

As the 8168 wasn't supported by that version this patch simply removes the bogus write from mac versions <= RTL_GIGA_MAC_VER_06.

[The change above makes sense for the 8101/8102 too -- Ueimor]

---
 drivers/net/r8169.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/r8169.c +4 -2
@@ -1438,8 +1438,10 @@ static void rtl8169_init_phy(struct net_
 
 	rtl_hw_phy_config(dev);
 
-	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
-	RTL_W8(0x82, 0x01);
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
+		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+		RTL_W8(0x82, 0x01);
+	}
 
 	pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
 
author
#37 lore raw

PATCH 37/60 ALSA: asoc: restrict sample rate and size in Freescale MPC8610 sound drivers

In reply to Greg KH

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

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

From: Timur Tabi <[email protected]>

Upstream-commid-id: be41e941d5f1a48bde7f44d09d56e8d2605f98e1

The Freescale MPC8610 SSI device has the option of using one clock for both transmit and receive (synchronous mode), or independent clocks (asynchronous). The SSI driver, however, programs the SSI into synchronous mode and then tries to program the clock registers independently. The result is that the wrong sample size is usually generated during recording.

This patch fixes the discrepancy by restricting the sample rate and sample size of the playback and capture streams. The SSI driver remembers which stream is opened first. When a second stream is opened, that stream is constrained to the same sample rate and size as the first stream.

A future version of this driver will lift the sample size restriction. Supporting independent sample rates is more difficult, because only certain codecs provide dual independent clocks.

---
 sound/soc/fsl/fsl_dma.c |    7 +++-
 sound/soc/fsl/fsl_ssi.c |   74 +++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 70 insertions(+), 11 deletions(-)
sound/soc/fsl/fsl_dma.c +6 -1
@@ -132,12 +132,17 @@ struct fsl_dma_private {
  * Since each link descriptor has a 32-bit byte count field, we set
  * period_bytes_max to the largest 32-bit number.  We also have no maximum
  * number of periods.
+ *
+ * Note that we specify SNDRV_PCM_INFO_JOINT_DUPLEX here, but only because a
+ * limitation in the SSI driver requires the sample rates for playback and
+ * capture to be the same.
  */
 static const struct snd_pcm_hardware fsl_dma_hardware = {
 
 	.info   		= SNDRV_PCM_INFO_INTERLEAVED |
 				  SNDRV_PCM_INFO_MMAP |
-				  SNDRV_PCM_INFO_MMAP_VALID,
+				  SNDRV_PCM_INFO_MMAP_VALID |
+				  SNDRV_PCM_INFO_JOINT_DUPLEX,
 	.formats		= FSLDMA_PCM_FORMATS,
 	.rates  		= FSLDMA_PCM_RATES,
 	.rate_min       	= 5512,
sound/soc/fsl/fsl_ssi.c +64 -10

115 lines not on this page · raw message

author
#38 lore raw

PATCH 38/60 i2c: Fix NULL pointer dereference in i2c_new_probed_device

In reply to Greg KH

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

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

From: Hans Verkuil <[email protected]>

Already in Linus' tree:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b25b791b13aaa336b56c4f9bd417ff126363f80b

Fix a NULL pointer dereference that happened when calling i2c_new_probed_device on one of the addresses for which we use byte reads instead of quick write for detection purpose (that is: 0x30-0x37 and 0x50-0x5f).

---
 drivers/i2c/i2c-core.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/i2c/i2c-core.c +3 -1
@@ -1196,9 +1196,11 @@ i2c_new_probed_device(struct i2c_adapter
 		if ((addr_list[i] & ~0x07) == 0x30
 		 || (addr_list[i] & ~0x0f) == 0x50
 		 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
+			union i2c_smbus_data data;
+
 			if (i2c_smbus_xfer(adap, addr_list[i], 0,
 					   I2C_SMBUS_READ, 0,
-					   I2C_SMBUS_BYTE, NULL) >= 0)
+					   I2C_SMBUS_BYTE, &data) >= 0)
 				break;
 		} else {
 			if (i2c_smbus_xfer(adap, addr_list[i], 0,
author
#39 lore raw

PATCH 39/60 i2c: Let users select algorithm drivers manually again

In reply to Greg KH

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

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

Already in Linus' tree:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8d24f8dcb7ead491704e274883b2c627062f6235

In kernel 2.6.26, the ability to select I2C algorithm drivers manually was removed, as all in-kernel drivers do that automatically. However there were some complaints that it was a problem for out-of-tree I2C bus drivers. In order to address these complaints, let's allow manual selection of these drivers again, but still hide them by default for better general user experience.

This closes bug #11140:
http://bugzilla.kernel.org/show_bug.cgi?id=11140

---
 drivers/i2c/Kconfig       |   14 ++++++++++++++
 drivers/i2c/algos/Kconfig |   11 ++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)
drivers/i2c/algos/Kconfig +8 -3
@@ -2,15 +2,20 @@
 # I2C algorithm drivers configuration
 #
 
+menu "I2C Algorithms"
+	depends on !I2C_HELPER_AUTO
+
 config I2C_ALGOBIT
-	tristate
+	tristate "I2C bit-banging interfaces"
 
 config I2C_ALGOPCF
-	tristate
+	tristate "I2C PCF 8584 interfaces"
 
 config I2C_ALGOPCA
-	tristate
+	tristate "I2C PCA 9564 interfaces"
 
 config I2C_ALGO_SGI
 	tristate
 	depends on SGI_IP22 || SGI_IP32 || X86_VISWS
+
+endmenu
drivers/i2c/Kconfig +14 -0
@@ -38,6 +38,20 @@ config I2C_CHARDEV
 	  This support is also available as a module.  If so, the module 
 	  will be called i2c-dev.
 
+config I2C_HELPER_AUTO
+	bool "Autoselect pertinent helper modules"
+	default y
+	help
+	  Some I2C bus drivers require so-called "I2C algorithm" modules
+	  to work. These are basically software-only abstractions of generic
+	  I2C interfaces. This option will autoselect them so that you don't
+	  have to care.
+
+	  Unselect this only if you need to enable additional helper
+	  modules, for example for use with external I2C bus drivers.
+
+	  In doubt, say Y.
+
 source drivers/i2c/algos/Kconfig
 source drivers/i2c/busses/Kconfig
 source drivers/i2c/chips/Kconfig
author
#40 lore raw

PATCH 40/60 ALSA: ASoC: fix SNDCTL_DSP_SYNC support in Freescale 8610 sound drivers

In reply to Greg KH

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

------------------
From: Timur Tabi <[email protected]>

Upstream-commit-id: bf9c8c9ddef7ef761ae9747349175adad0ef16ce

If an OSS application calls SNDCTL_DSP_SYNC, then ALSA will call the driver's _hw_params and _prepare functions again. On the Freescale MPC8610 DMA ASoC driver, this caused the DMA controller to be unneccessarily re-programmed, and apparently it doesn't like that. The DMA will then not operate when instructed. This patch relocates much of the DMA programming to fsl_dma_open(), which is called only once.

---
 sound/soc/fsl/fsl_dma.c |  235 +++++++++++++++++++++++++-----------------------
 1 file changed, 124 insertions(+), 111 deletions(-)
sound/soc/fsl/fsl_dma.c +124 -111
@@ -327,14 +327,75 @@ static int fsl_dma_new(struct snd_card *
  * fsl_dma_open: open a new substream.
  *
  * Each substream has its own DMA buffer.
+ *
+ * ALSA divides the DMA buffer into N periods.  We create NUM_DMA_LINKS link
+ * descriptors that ping-pong from one period to the next.  For example, if
+ * there are six periods and two link descriptors, this is how they look
+ * before playback starts:
+ *
+ *      	   The last link descriptor
+ *   ____________  points back to the first
+ *  |   	 |
+ *  V   	 |
+ *  ___    ___   |
+ * |   |->|   |->|
+ * |___|  |___|
+ *   |      |
+ *   |      |
+ *   V      V
+ *  _________________________________________
+ * |      |      |      |      |      |      |  The DMA buffer is
+ * |      |      |      |      |      |      |    divided into 6 parts
+ * |______|______|______|______|______|______|
+ *
+ * and here's how they look after the first period is finished playing:
+ *
+ *   ____________
+ *  |   	 |
+ *  V   	 |
+ *  ___    ___   |
+ * |   |->|   |->|
+ * |___|  |___|
+ *   |      |
+ *   |______________
+ *          |       |
+ *          V       V
+ *  _________________________________________
+ * |      |      |      |      |      |      |
+ * |      |      |      |      |      |      |
+ * |______|______|______|______|______|______|
+ *
+ * The first link descriptor now points to the third period.  The DMA
+ * controller is currently playing the second period.  When it finishes, it
+ * will jump back to the first descriptor and play the third period.
+ *
+ * There are four reasons we do this:
+ *
+ * 1. The only way to get the DMA controller to automatically restart the
+ *    transfer when it gets to the end of the buffer is to use chaining
+ *    mode.  Basic direct mode doesn't offer that feature.
+ * 2. We need to receive an interrupt at the end of every period.  The DMA
+ *    controller can generate an interrupt at the end of every link transfer
+ *    (aka segment).  Making each period into a DMA segment will give us the
+ *    interrupts we need.
+ * 3. By creating only two link descriptors, regardless of the number of
+ *    periods, we do not need to reallocate the link descriptors if the
+ *    number of periods changes.
+ * 4. All of the audio data is still stored in a single, contiguous DMA
+ *    buffer, which is what ALSA expects.  We're just dividing it into
+ *    contiguous parts, and creating a link descriptor for each one.
  */
 static int fsl_dma_open(struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_dma_private *dma_private;
+	struct ccsr_dma_channel __iomem *dma_channel;
 	dma_addr_t ld_buf_phys;
+	u64 temp_link;  	/* Pointer to next link descriptor */
+	u32 mr;
 	unsigned int channel;
 	int ret = 0;
+	unsigned int i;
 
 	/*
 	 * Reject any DMA buffer whose size is not a multiple of the period
@@ -395,68 +456,74 @@ static int fsl_dma_open(struct snd_pcm_s
 	snd_soc_set_runtime_hwparams(substream, &fsl_dma_hardware);
 	runtime->private_data = dma_private;
 
+	/* Program the fixed DMA controller parameters */
+
+	dma_channel = dma_private->dma_channel;
+
+	temp_link = dma_private->ld_buf_phys +
+		sizeof(struct fsl_dma_link_descriptor);
+
+	for (i = 0; i < NUM_DMA_LINKS; i++) {
+		struct fsl_dma_link_descriptor *link = &dma_private->link[i];
+
+		link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
+		link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
+		link->next = cpu_to_be64(temp_link);
+
+		temp_link += sizeof(struct fsl_dma_link_descriptor);
+	}
+	/* The last link descriptor points to the first */
+	dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
+
+	/* Tell the DMA controller where the first link descriptor is */
+	out_be32(&dma_channel->clndar,
+		CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
+	out_be32(&dma_channel->eclndar,
+		CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
+
+	/* The manual says the BCR must be clear before enabling EMP */
+	out_be32(&dma_channel->bcr, 0);
+
+	/*
+	 * Program the mode register for interrupts, external master control,
+	 * and source/destination hold.  Also clear the Channel Abort bit.
+	 */
+	mr = in_be32(&dma_channel->mr) &
+		~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
+
+	/*
+	 * We want External Master Start and External Master Pause enabled,
+	 * because the SSI is controlling the DMA controller.  We want the DMA
+	 * controller to be set up in advance, and then we signal only the SSI
+	 * to start transferring.
+	 *
+	 * We want End-Of-Segment Interrupts enabled, because this will generate
+	 * an interrupt at the end of each segment (each link descriptor
+	 * represents one segment).  Each DMA segment is the same thing as an
+	 * ALSA period, so this is how we get an interrupt at the end of every
+	 * period.
+	 *
+	 * We want Error Interrupt enabled, so that we can get an error if
+	 * the DMA controller is mis-programmed somehow.
+	 */
+	mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
+		CCSR_DMA_MR_EMS_EN;
+
+	/* For playback, we want the destination address to be held.  For
+	   capture, set the source address to be held. */
+	mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
+
+	out_be32(&dma_channel->mr, mr);
+
 	return 0;
 }
 
 /**
- * fsl_dma_hw_params: allocate the DMA buffer and the DMA link descriptors.
- *
- * ALSA divides the DMA buffer into N periods.  We create NUM_DMA_LINKS link
- * descriptors that ping-pong from one period to the next.  For example, if
- * there are six periods and two link descriptors, this is how they look
- * before playback starts:
- *
- *      	   The last link descriptor
- *   ____________  points back to the first
- *  |   	 |
- *  V   	 |
- *  ___    ___   |
- * |   |->|   |->|
- * |___|  |___|
- *   |      |
- *   |      |
- *   V      V
- *  _________________________________________
- * |      |      |      |      |      |      |  The DMA buffer is
- * |      |      |      |      |      |      |    divided into 6 parts
- * |______|______|______|______|______|______|
- *
- * and here's how they look after the first period is finished playing:
- *
- *   ____________
- *  |   	 |
- *  V   	 |
- *  ___    ___   |
- * |   |->|   |->|
- * |___|  |___|
- *   |      |
- *   |______________
- *          |       |
- *          V       V
- *  _________________________________________
- * |      |      |      |      |      |      |
- * |      |      |      |      |      |      |
- * |______|______|______|______|______|______|
+ * fsl_dma_hw_params: continue initializing the DMA links
  *
- * The first link descriptor now points to the third period.  The DMA
- * controller is currently playing the second period.  When it finishes, it
- * will jump back to the first descriptor and play the third period.
- *
- * There are four reasons we do this:
- *
- * 1. The only way to get the DMA controller to automatically restart the
- *    transfer when it gets to the end of the buffer is to use chaining
- *    mode.  Basic direct mode doesn't offer that feature.
- * 2. We need to receive an interrupt at the end of every period.  The DMA
- *    controller can generate an interrupt at the end of every link transfer
- *    (aka segment).  Making each period into a DMA segment will give us the
- *    interrupts we need.
- * 3. By creating only two link descriptors, regardless of the number of
- *    periods, we do not need to reallocate the link descriptors if the
- *    number of periods changes.
- * 4. All of the audio data is still stored in a single, contiguous DMA
- *    buffer, which is what ALSA expects.  We're just dividing it into
- *    contiguous parts, and creating a link descriptor for each one.
+ * This function obtains hardware parameters about the opened stream and
+ * programs the DMA controller accordingly.
  *
  * Note that due to a quirk of the SSI's STX register, the target address
  * for the DMA operations depends on the sample size.  So we don't program
@@ -468,11 +535,8 @@ static int fsl_dma_hw_params(struct snd_
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct fsl_dma_private *dma_private = runtime->private_data;
-	struct ccsr_dma_channel __iomem *dma_channel = dma_private->dma_channel;
 
 	dma_addr_t temp_addr;   /* Pointer to next period */
-	u64 temp_link;  	/* Pointer to next link descriptor */
-	u32 mr; 		/* Temporary variable for MR register */
 
 	unsigned int i;
 
@@ -490,8 +554,6 @@ static int fsl_dma_hw_params(struct snd_
 		dma_private->dma_buf_next = dma_private->dma_buf_phys;
 
 	/*
-	 * Initialize each link descriptor.
-	 *
 	 * The actual address in STX0 (destination for playback, source for
 	 * capture) is based on the sample size, but we don't know the sample
 	 * size in this function, so we'll have to adjust that later.  See
@@ -507,16 +569,11 @@ static int fsl_dma_hw_params(struct snd_
 	 * buffer itself.
 	 */
 	temp_addr = substream->dma_buffer.addr;
-	temp_link = dma_private->ld_buf_phys +
-		sizeof(struct fsl_dma_link_descriptor);
 
 	for (i = 0; i < NUM_DMA_LINKS; i++) {
 		struct fsl_dma_link_descriptor *link = &dma_private->link[i];
 
 		link->count = cpu_to_be32(period_size);
-		link->source_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
-		link->dest_attr = cpu_to_be32(CCSR_DMA_ATR_SNOOP);
-		link->next = cpu_to_be64(temp_link);
 
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 			link->source_addr = cpu_to_be32(temp_addr);
@@ -524,51 +581,7 @@ static int fsl_dma_hw_params(struct snd_
 			link->dest_addr = cpu_to_be32(temp_addr);
 
 		temp_addr += period_size;
-		temp_link += sizeof(struct fsl_dma_link_descriptor);
 	}
-	/* The last link descriptor points to the first */
-	dma_private->link[i - 1].next = cpu_to_be64(dma_private->ld_buf_phys);
-
-	/* Tell the DMA controller where the first link descriptor is */
-	out_be32(&dma_channel->clndar,
-		CCSR_DMA_CLNDAR_ADDR(dma_private->ld_buf_phys));
-	out_be32(&dma_channel->eclndar,
-		CCSR_DMA_ECLNDAR_ADDR(dma_private->ld_buf_phys));
-
-	/* The manual says the BCR must be clear before enabling EMP */
-	out_be32(&dma_channel->bcr, 0);
-
-	/*
-	 * Program the mode register for interrupts, external master control,
-	 * and source/destination hold.  Also clear the Channel Abort bit.
-	 */
-	mr = in_be32(&dma_channel->mr) &
-		~(CCSR_DMA_MR_CA | CCSR_DMA_MR_DAHE | CCSR_DMA_MR_SAHE);
-
-	/*
-	 * We want External Master Start and External Master Pause enabled,
-	 * because the SSI is controlling the DMA controller.  We want the DMA
-	 * controller to be set up in advance, and then we signal only the SSI
-	 * to start transfering.
-	 *
-	 * We want End-Of-Segment Interrupts enabled, because this will generate
-	 * an interrupt at the end of each segment (each link descriptor
-	 * represents one segment).  Each DMA segment is the same thing as an
-	 * ALSA period, so this is how we get an interrupt at the end of every
-	 * period.
-	 *
-	 * We want Error Interrupt enabled, so that we can get an error if
-	 * the DMA controller is mis-programmed somehow.
-	 */
-	mr |= CCSR_DMA_MR_EOSIE | CCSR_DMA_MR_EIE | CCSR_DMA_MR_EMP_EN |
-		CCSR_DMA_MR_EMS_EN;
-
-	/* For playback, we want the destination address to be held.  For
-	   capture, set the source address to be held. */
-	mr |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
-		CCSR_DMA_MR_DAHE : CCSR_DMA_MR_SAHE;
-
-	out_be32(&dma_channel->mr, mr);
 
 	return 0;
 }
author
#41 lore raw

PATCH 41/60 x86: amd opteron TOM2 mask val fix

In reply to Greg KH

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

------------------
From: Yinghai Lu <[email protected]>

commit 8004dd965b13b01a96def054d420f6df7ff22d53 upstream.

there is a typo in the mask value, need to remove that extra 0, to avoid 4bit clearing.

Cc maximilian attems <[email protected]>
Cc Peter Palfrader <[email protected]>
Cc dann frazier <[email protected]>
---
 arch/x86/kernel/cpu/mtrr/generic.c |    2 +-
 arch/x86/pci/k8-bus_64.c           |    4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/kernel/cpu/mtrr/generic.c +1 -1
@@ -219,7 +219,7 @@ void __init get_mtrr_state(void)
 		tom2 = hi;
 		tom2 <<= 32;
 		tom2 |= lo;
-		tom2 &= 0xffffff8000000ULL;
+		tom2 &= 0xffffff800000ULL;
 	}
 	if (mtrr_show) {
 		int high_width;
arch/x86/pci/k8-bus_64.c +2 -2
@@ -384,7 +384,7 @@ static int __init early_fill_mp_bus_info
 	/* need to take out [0, TOM) for RAM*/
 	address = MSR_K8_TOP_MEM1;
 	rdmsrl(address, val);
-	end = (val & 0xffffff8000000ULL);
+	end = (val & 0xffffff800000ULL);
 	printk(KERN_INFO "TOM: %016lx aka %ldM\n", end, end>>20);
 	if (end < (1ULL<<32))
 		update_range(range, 0, end - 1);
@@ -478,7 +478,7 @@ static int __init early_fill_mp_bus_info
 		/* TOP_MEM2 */
 		address = MSR_K8_TOP_MEM2;
 		rdmsrl(address, val);
-		end = (val & 0xffffff8000000ULL);
+		end = (val & 0xffffff800000ULL);
 		printk(KERN_INFO "TOM2: %016lx aka %ldM\n", end, end>>20);
 		update_range(range, 1ULL<<32, end - 1);
 	}
author
#42 lore raw

PATCH 42/60 ide: it821x in pass-through mode segfaults in 2.6.26-stable

In reply to Greg KH

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

------------------
commit 84e0f3f6c1e26588fdcb9f1b0f99d0275229bc99 upstream

The driver of ITE8212 in pass-through mode (it8212.noraid=1 on cmndline) attempts to use the field .dma_host_set' of the struct ide_dma_ops in ide_config_drive_speed' which is set to NULL by default.

So give a value to all fields of the struct ide_dma_ops.

---
 drivers/ide/pci/it821x.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/ide/pci/it821x.c +6 -0
@@ -512,8 +512,14 @@ static void __devinit it821x_quirkproc(i
 }
 
 static struct ide_dma_ops it821x_pass_through_dma_ops = {
+	.dma_host_set		= ide_dma_host_set,
+	.dma_setup		= ide_dma_setup,
+	.dma_exec_cmd		= ide_dma_exec_cmd,
 	.dma_start		= it821x_dma_start,
 	.dma_end		= it821x_dma_end,
+	.dma_test_irq		= ide_dma_test_irq,
+	.dma_timeout		= ide_dma_timeout,
+	.dma_lost_irq		= ide_dma_lost_irq,
 };
 
 /**
author
#43 lore raw

PATCH 43/60 CIFS: Fix compiler warning on 64-bit

In reply to Greg KH

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

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

commit 04e1e0cccade330ab3715ce59234f7e3b087e246 upstream.

---
 fs/cifs/asn1.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/asn1.c +1 -1
@@ -400,7 +400,7 @@ asn1_oid_decode(struct asn1_ctx *ctx,
 	size = eoc - ctx->pointer + 1;
 
 	/* first subid actually encodes first two subids */
-	if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
+	if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
 		return 0;
 
 	*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
author
#44 lore raw

PATCH 44/60 radeon: misc corrections

In reply to Greg KH

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

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

Commit efc491814308f89d5ef6c4fe19ae4552a67d4132 upstream

radeon: misc corrections

I have a new PCI-E radeon RV380 series card (PCI device ID 5b64) that hangs in my sparc64 boxes when the init scripts set the font. The problem goes away if I disable acceleration.

I haven't figured out that bug yet, but along the way I found some corrections to make based upon some auditing.

1) The RB2D_DC_FLUSH_ALL value used by the kernel fb driver and the XORG video driver differ. I've made the kernel match what XORG is using.

2) In radeonfb_engine_reset() we have top-level code structure that roughly looks like:

	if (family is 300, 350, or V350)
		do this;
	else
		do that;
	...
	if (family is NOT 300, OR
	    family is NOT 350, OR
	    family is NOT V350)
		do another thing;

this last conditional makes no sense, is always true, and obviously was likely meant to be "family is NOT 300, 350, or V350". So I've made the code match the intent.

---
 drivers/video/aty/radeon_accel.c |    4 ++--
 include/video/radeon.h           |    5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/video/aty/radeon_accel.c +2 -2
@@ -249,8 +249,8 @@ void radeonfb_engine_reset(struct radeon
 	INREG(HOST_PATH_CNTL);
 	OUTREG(HOST_PATH_CNTL, host_path_cntl);
 
-	if (rinfo->family != CHIP_FAMILY_R300 ||
-	    rinfo->family != CHIP_FAMILY_R350 ||
+	if (rinfo->family != CHIP_FAMILY_R300 &&
+	    rinfo->family != CHIP_FAMILY_R350 &&
 	    rinfo->family != CHIP_FAMILY_RV350)
 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
 
include/video/radeon.h +3 -2
@@ -527,8 +527,9 @@
 
 
 /* DSTCACHE_CTLSTAT bit constants */
-#define RB2D_DC_FLUSH				   (3 << 0)
-#define RB2D_DC_FLUSH_ALL			   0xf
+#define RB2D_DC_FLUSH_2D			   (1 << 0)
+#define RB2D_DC_FREE_2D				   (1 << 2)
+#define RB2D_DC_FLUSH_ALL			   (RB2D_DC_FLUSH_2D | RB2D_DC_FREE_2D)
 #define RB2D_DC_BUSY				   (1 << 31)
 
 
author
#45 lore raw

PATCH 45/60 cs5520: add enablebits checking

In reply to Greg KH

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

------------------
From: Bartlomiej Zolnierkiewicz <[email protected]>

upstream commit is 24307ffabd5b39bad443641f54b12ee2ba7a38ac

Based on sparse comments in OpenFirmware code
(no Cx5510/Cx5520 datasheet here).

This fixes 2.6.26 regression reported by TAKADA
and caused by addition of warm-plug support.

---
 drivers/ide/pci/cs5520.c |    1 +
 1 file changed, 1 insertion(+)
drivers/ide/pci/cs5520.c +1 -0
@@ -123,6 +123,7 @@ static const struct ide_dma_ops cs5520_d
 #define DECLARE_CS_DEV(name_str)				\
 	{							\
 		.name		= name_str,			\
+		.enablebits	= { {0x60, 0x01, 0x01}, {0x60, 0x02, 0x02} }, \
 		.port_ops	= &cs5520_port_ops,		\
 		.dma_ops	= &cs5520_dma_ops,		\
 		.host_flags	= IDE_HFLAG_ISA_PORTS |		\
author
#46 lore raw

PATCH 46/60 rtl8187: Fix lockups due to concurrent access to config routine

In reply to Greg KH

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

------------------
From: Larry Finger <[email protected]>

With the rtl8187 driver, the config routine is not protected against access before a previous call has completed. When this happens, the TX loopback that is needed to change channels may cause the chip to be locked with a reset needed to restore communications. This patch entered mainline as commit 7dcdd073bf78bb6958bbc12a1a47754a0f3c4721.

The problem was found by Herton Ronaldo Krzesinski <[email protected]>, who also suggested this type of fix.

---
 drivers/net/wireless/rtl8187.h     |    4 ++++
 drivers/net/wireless/rtl8187_dev.c |    3 +++
 2 files changed, 7 insertions(+)
drivers/net/wireless/rtl8187_dev.c +3 -0
@@ -580,6 +580,7 @@ static int rtl8187_config(struct ieee802
 	struct rtl8187_priv *priv = dev->priv;
 	u32 reg;
 
+	mutex_lock(&priv->conf_mutex);
 	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
 	/* Enable TX loopback on MAC level to avoid TX during channel
 	 * changes, as this has be seen to causes problems and the
@@ -610,6 +611,7 @@ static int rtl8187_config(struct ieee802
 	rtl818x_iowrite16(priv, &priv->map->ATIMTR_INTERVAL, 100);
 	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL, 100);
 	rtl818x_iowrite16(priv, &priv->map->BEACON_INTERVAL_TIME, 100);
+	mutex_unlock(&priv->conf_mutex);
 	return 0;
 }
 
@@ -814,6 +816,7 @@ static int __devinit rtl8187_probe(struc
 		printk(KERN_ERR "rtl8187: Cannot register device\n");
 		goto err_free_dev;
 	}
+	mutex_init(&priv->conf_mutex);
 
 	printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n",
 	       wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
drivers/net/wireless/rtl8187.h +4 -0
@@ -67,6 +67,10 @@ struct rtl8187_priv {
 	const struct rtl818x_rf_ops *rf;
 	struct ieee80211_vif *vif;
 	int mode;
+	/* The mutex protects the TX loopback state.
+	 * Any attempt to set channels concurrently locks the device.
+	 */
+	struct mutex conf_mutex;
 
 	/* rtl8187 specific */
 	struct ieee80211_channel channels[14];
author
#47 lore raw

PATCH 47/60 sparc64: Fix end-of-stack checking in save_stack_trace().

In reply to Greg KH

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

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

[ Upstream commit 433c5f706856689be25928a99636e724fb3ea7cf ]

Bug reported by Alexander Beregalov.

Before we dereference the stack frame or try to peek at the pt_regs magic value, make sure the entire object is within the kernel stack bounds.

---
 arch/sparc64/kernel/stacktrace.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/sparc64/kernel/stacktrace.c +4 -2
@@ -25,13 +25,15 @@ void save_stack_trace(struct stack_trace
 
 		/* Bogus frame pointer? */
 		if (fp < (thread_base + sizeof(struct thread_info)) ||
-		    fp >= (thread_base + THREAD_SIZE))
+		    fp > (thread_base + THREAD_SIZE - sizeof(struct sparc_stackf)))
 			break;
 
 		sf = (struct sparc_stackf *) fp;
 		regs = (struct pt_regs *) (sf + 1);
 
-		if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
+		if (((unsigned long)regs <=
+		     (thread_base + THREAD_SIZE - sizeof(*regs))) &&
+		    (regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
 			if (!(regs->tstate & TSTATE_PRIV))
 				break;
 			pc = regs->tpc;
author
#48 lore raw

PATCH 48/60 sparc64: Fix recursion in stack overflow detection handling.

In reply to Greg KH

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

------------------
[ Upstream commit c7498081a6f5d96c9f3243b6b5e020352903bfd2 ]

The calls down into prom_printf() when we detect an overflowed stack can recurse again since the overflow stack will be "below" the current kernel stack limit.

Prevent this by just returning straight if we are on the stack overflow safe stack already.

---
 arch/sparc64/lib/mcount.S |   17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)
arch/sparc64/lib/mcount.S +14 -3
@@ -45,12 +45,23 @@ _mcount:
 	sub		%g3, STACK_BIAS, %g3
 	cmp		%sp, %g3
 	bg,pt		%xcc, 1f
-	 sethi		%hi(panicstring), %g3
+	 nop
+	/* If we are already on ovstack, don't hop onto it
+	 * again, we are already trying to output the stack overflow
+	 * message.
+	 */
 	sethi		%hi(ovstack), %g7		! cant move to panic stack fast enough
 	 or		%g7, %lo(ovstack), %g7
-	add		%g7, OVSTACKSIZE, %g7
+	add		%g7, OVSTACKSIZE, %g3
+	sub		%g3, STACK_BIAS + 192, %g3
 	sub		%g7, STACK_BIAS, %g7
-	mov		%g7, %sp
+	cmp		%sp, %g7
+	blu,pn		%xcc, 2f
+	 cmp		%sp, %g3
+	bleu,pn		%xcc, 1f
+	 nop
+2:	mov		%g3, %sp
+	sethi		%hi(panicstring), %g3
 	call		prom_printf
 	 or		%g3, %lo(panicstring), %o0
 	call		prom_halt
author
#49 lore raw

PATCH 49/60 sparc64: Make global reg dumping even more useful.

In reply to Greg KH

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

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

[ Upstream commit 5afe27380bc42454254c9c83c045240249c15e35 ]

Record one more level of stack frame program counter.

Particularly when lockdep and all sorts of spinlock debugging is enabled, figuring out the caller of spin_lock() is difficult when the cpu is stuck on the lock.

---
 arch/sparc64/kernel/process.c |   35 +++++++++++++++++++++++++++++------
 arch/sparc64/mm/ultra.S       |    7 +++++++
 include/asm-sparc64/ptrace.h  |    8 ++++----
 3 files changed, 40 insertions(+), 10 deletions(-)
arch/sparc64/kernel/process.c +29 -6
@@ -305,6 +305,19 @@ void show_regs(struct pt_regs *regs)
 struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
 static DEFINE_SPINLOCK(global_reg_snapshot_lock);
 
+static bool kstack_valid(struct thread_info *tp, struct reg_window *rw)
+{
+	unsigned long thread_base, fp;
+
+	thread_base = (unsigned long) tp;
+	fp = (unsigned long) rw;
+
+	if (fp < (thread_base + sizeof(struct thread_info)) ||
+	    fp >= (thread_base + THREAD_SIZE))
+		return false;
+	return true;
+}
+
 static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
 			      int this_cpu)
 {
@@ -316,14 +329,22 @@ static void __global_reg_self(struct thr
 	global_reg_snapshot[this_cpu].o7 = regs->u_regs[UREG_I7];
 
 	if (regs->tstate & TSTATE_PRIV) {
+		struct thread_info *tp = current_thread_info();
 		struct reg_window *rw;
 
 		rw = (struct reg_window *)
 			(regs->u_regs[UREG_FP] + STACK_BIAS);
-		global_reg_snapshot[this_cpu].i7 = rw->ins[7];
-	} else
+		if (kstack_valid(tp, rw)) {
+			global_reg_snapshot[this_cpu].i7 = rw->ins[7];
+			rw = (struct reg_window *)
+				(rw->ins[6] + STACK_BIAS);
+			if (kstack_valid(tp, rw))
+				global_reg_snapshot[this_cpu].rpc = rw->ins[7];
+		}
+	} else {
 		global_reg_snapshot[this_cpu].i7 = 0;
-
+		global_reg_snapshot[this_cpu].rpc = 0;
+	}
 	global_reg_snapshot[this_cpu].thread = tp;
 }
 
@@ -384,12 +405,14 @@ static void sysrq_handle_globreg(int key
 			sprint_symbol(buffer, gp->o7);
 			printk("O7[%s] ", buffer);
 			sprint_symbol(buffer, gp->i7);
-			printk("I7[%s]\n", buffer);
+			printk("I7[%s] ", buffer);
+			sprint_symbol(buffer, gp->rpc);
+			printk("RPC[%s]\n", buffer);
 		} else
 #endif
 		{
-			printk("             TPC[%lx] O7[%lx] I7[%lx]\n",
-			       gp->tpc, gp->o7, gp->i7);
+			printk("             TPC[%lx] O7[%lx] I7[%lx] RPC[%lx]\n",
+			       gp->tpc, gp->o7, gp->i7, gp->rpc);
 		}
 	}
 
arch/sparc64/mm/ultra.S +7 -0
@@ -531,6 +531,13 @@ xcall_fetch_glob_regs:
 	stx		%g7, [%g1 + GR_SNAP_TNPC]
 	stx		%o7, [%g1 + GR_SNAP_O7]
 	stx		%i7, [%g1 + GR_SNAP_I7]
+	/* Don't try this at home kids... */
+	rdpr		%cwp, %g2
+	sub		%g2, 1, %g7
+	wrpr		%g7, %cwp
+	mov		%i7, %g7
+	wrpr		%g2, %cwp
+	stx		%g7, [%g1 + GR_SNAP_RPC]
 	sethi		%hi(trap_block), %g7
 	or		%g7, %lo(trap_block), %g7
 	sllx		%g2, TRAP_BLOCK_SZ_SHIFT, %g2
include/asm-sparc64/ptrace.h +4 -4
@@ -134,9 +134,9 @@ struct global_reg_snapshot {
 	unsigned long		tnpc;
 	unsigned long		o7;
 	unsigned long		i7;
+	unsigned long		rpc;
 	struct thread_info	*thread;
 	unsigned long		pad1;
-	unsigned long		pad2;
 };
 
 #define __ARCH_WANT_COMPAT_SYS_PTRACE
@@ -314,9 +314,9 @@ extern void __show_regs(struct pt_regs *
 #define GR_SNAP_TNPC	0x10
 #define GR_SNAP_O7	0x18
 #define GR_SNAP_I7	0x20
-#define GR_SNAP_THREAD	0x28
-#define GR_SNAP_PAD1	0x30
-#define GR_SNAP_PAD2	0x38
+#define GR_SNAP_RPC	0x28
+#define GR_SNAP_THREAD	0x30
+#define GR_SNAP_PAD1	0x38
 
 #endif  /*  __KERNEL__  */
 
author
#50 lore raw

PATCH 50/60 sparc64: Implement IRQ stacks.

In reply to Greg KH

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

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

[ Upstream commit 4f70f7a91bffdcc39f088748dc678953eb9a3fbd ]

---
 arch/sparc64/kernel/irq.c        |   52 ++++++++++++++++++++++++++++++++++
 arch/sparc64/kernel/kstack.h     |   58 +++++++++++++++++++++++++++++++++++++++
 arch/sparc64/kernel/process.c    |   27 ++++--------------
 arch/sparc64/kernel/stacktrace.c |   10 ++----
 arch/sparc64/kernel/traps.c      |    7 ++--
 arch/sparc64/lib/mcount.S        |   22 ++++++++++++++
 arch/sparc64/mm/init.c           |   11 +++++++
 include/asm-sparc64/irq.h        |    4 ++
 8 files changed, 161 insertions(+), 30 deletions(-)
arch/sparc64/kernel/irq.c +52 -0
@@ -682,10 +682,32 @@ void ack_bad_irq(unsigned int virt_irq)
 	       ino, virt_irq);
 }
 
+void *hardirq_stack[NR_CPUS];
+void *softirq_stack[NR_CPUS];
+
+static __attribute__((always_inline)) void *set_hardirq_stack(void)
+{
+	void *orig_sp, *sp = hardirq_stack[smp_processor_id()];
+
+	__asm__ __volatile__("mov %%sp, %0" : "=r" (orig_sp));
+	if (orig_sp < sp ||
+	    orig_sp > (sp + THREAD_SIZE)) {
+		sp += THREAD_SIZE - 192 - STACK_BIAS;
+		__asm__ __volatile__("mov %0, %%sp" : : "r" (sp));
+	}
+
+	return orig_sp;
+}
+static __attribute__((always_inline)) void restore_hardirq_stack(void *orig_sp)
+{
+	__asm__ __volatile__("mov %0, %%sp" : : "r" (orig_sp));
+}
+
 void handler_irq(int irq, struct pt_regs *regs)
 {
 	unsigned long pstate, bucket_pa;
 	struct pt_regs *old_regs;
+	void *orig_sp;
 
 	clear_softint(1 << irq);
 
@@ -703,6 +725,8 @@ void handler_irq(int irq, struct pt_regs
 			       "i" (PSTATE_IE)
 			     : "memory");
 
+	orig_sp = set_hardirq_stack();
+
 	while (bucket_pa) {
 		struct irq_desc *desc;
 		unsigned long next_pa;
@@ -719,10 +743,38 @@ void handler_irq(int irq, struct pt_regs
 		bucket_pa = next_pa;
 	}
 
+	restore_hardirq_stack(orig_sp);
+
 	irq_exit();
 	set_irq_regs(old_regs);
 }
 
+void do_softirq(void)
+{
+	unsigned long flags;
+
+	if (in_interrupt())
+		return;
+
+	local_irq_save(flags);
+
+	if (local_softirq_pending()) {
+		void *orig_sp, *sp = softirq_stack[smp_processor_id()];
+
+		sp += THREAD_SIZE - 192 - STACK_BIAS;
+
+		__asm__ __volatile__("mov %%sp, %0\n\t"
+				     "mov %1, %%sp"
+				     : "=&r" (orig_sp)
+				     : "r" (sp));
+		__do_softirq();
+		__asm__ __volatile__("mov %0, %%sp"
+				     : : "r" (orig_sp));
+	}
+
+	local_irq_restore(flags);
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 void fixup_irqs(void)
 {
arch/sparc64/kernel/kstack.h new file +58 -0

58 lines not on this page · raw message

arch/sparc64/kernel/process.c +7 -20
@@ -55,6 +55,8 @@
 
 /* #define VERBOSE_SHOWREGS */
 
+#include "kstack.h"
+
 static void sparc64_yield(int cpu)
 {
 	if (tlb_type != hypervisor)
@@ -305,19 +307,6 @@ void show_regs(struct pt_regs *regs)
 struct global_reg_snapshot global_reg_snapshot[NR_CPUS];
 static DEFINE_SPINLOCK(global_reg_snapshot_lock);
 
-static bool kstack_valid(struct thread_info *tp, struct reg_window *rw)
-{
-	unsigned long thread_base, fp;
-
-	thread_base = (unsigned long) tp;
-	fp = (unsigned long) rw;
-
-	if (fp < (thread_base + sizeof(struct thread_info)) ||
-	    fp >= (thread_base + THREAD_SIZE))
-		return false;
-	return true;
-}
-
 static void __global_reg_self(struct thread_info *tp, struct pt_regs *regs,
 			      int this_cpu)
 {
@@ -334,11 +323,11 @@ static void __global_reg_self(struct thr
 
 		rw = (struct reg_window *)
 			(regs->u_regs[UREG_FP] + STACK_BIAS);
-		if (kstack_valid(tp, rw)) {
+		if (kstack_valid(tp, (unsigned long) rw)) {
 			global_reg_snapshot[this_cpu].i7 = rw->ins[7];
 			rw = (struct reg_window *)
 				(rw->ins[6] + STACK_BIAS);
-			if (kstack_valid(tp, rw))
+			if (kstack_valid(tp, (unsigned long) rw))
 				global_reg_snapshot[this_cpu].rpc = rw->ins[7];
 		}
 	} else {
@@ -899,7 +888,7 @@ out:
 unsigned long get_wchan(struct task_struct *task)
 {
 	unsigned long pc, fp, bias = 0;
-	unsigned long thread_info_base;
+	struct thread_info *tp;
 	struct reg_window *rw;
         unsigned long ret = 0;
 	int count = 0; 
@@ -908,14 +897,12 @@ unsigned long get_wchan(struct task_stru
             task->state == TASK_RUNNING)
 		goto out;
 
-	thread_info_base = (unsigned long) task_stack_page(task);
+	tp = task_thread_info(task);
 	bias = STACK_BIAS;
 	fp = task_thread_info(task)->ksp + bias;
 
 	do {
-		/* Bogus frame pointer? */
-		if (fp < (thread_info_base + sizeof(struct thread_info)) ||
-		    fp >= (thread_info_base + THREAD_SIZE))
+		if (!kstack_valid(tp, fp))
 			break;
 		rw = (struct reg_window *) fp;
 		pc = rw->ins[7];
arch/sparc64/kernel/stacktrace.c +4 -6
@@ -4,6 +4,8 @@
 #include <asm/ptrace.h>
 #include <asm/stacktrace.h>
 
+#include "kstack.h"
+
 void save_stack_trace(struct stack_trace *trace)
 {
 	unsigned long ksp, fp, thread_base;
@@ -23,17 +25,13 @@ void save_stack_trace(struct stack_trace
 		struct pt_regs *regs;
 		unsigned long pc;
 
-		/* Bogus frame pointer? */
-		if (fp < (thread_base + sizeof(struct thread_info)) ||
-		    fp > (thread_base + THREAD_SIZE - sizeof(struct sparc_stackf)))
+		if (!kstack_valid(tp, fp))
 			break;
 
 		sf = (struct sparc_stackf *) fp;
 		regs = (struct pt_regs *) (sf + 1);
 
-		if (((unsigned long)regs <=
-		     (thread_base + THREAD_SIZE - sizeof(*regs))) &&
-		    (regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
+		if (kstack_is_trap_frame(tp, regs)) {
 			if (!(regs->tstate & TSTATE_PRIV))
 				break;
 			pc = regs->tpc;
arch/sparc64/kernel/traps.c +3 -4
@@ -43,6 +43,7 @@
 #include <asm/prom.h>
 
 #include "entry.h"
+#include "kstack.h"
 
 /* When an irrecoverable trap occurs at tl > 0, the trap entry
  * code logs the trap state registers at every level in the trap
@@ -2120,14 +2121,12 @@ void show_stack(struct task_struct *tsk,
 		struct pt_regs *regs;
 		unsigned long pc;
 
-		/* Bogus frame pointer? */
-		if (fp < (thread_base + sizeof(struct thread_info)) ||
-		    fp >= (thread_base + THREAD_SIZE))
+		if (!kstack_valid(tp, fp))
 			break;
 		sf = (struct sparc_stackf *) fp;
 		regs = (struct pt_regs *) (sf + 1);
 
-		if ((regs->magic & ~0x1ff) == PT_REGS_MAGIC) {
+		if (kstack_is_trap_frame(tp, regs)) {
 			if (!(regs->tstate & TSTATE_PRIV))
 				break;
 			pc = regs->tpc;
arch/sparc64/lib/mcount.S +22 -0
@@ -46,6 +46,28 @@ _mcount:
 	cmp		%sp, %g3
 	bg,pt		%xcc, 1f
 	 nop
+	lduh		[%g6 + TI_CPU], %g1
+	sethi		%hi(hardirq_stack), %g3
+	or		%g3, %lo(hardirq_stack), %g3
+	sllx		%g1, 3, %g1
+	ldx		[%g3 + %g1], %g7
+	sub		%g7, STACK_BIAS, %g7
+	cmp		%sp, %g7
+	bleu,pt		%xcc, 2f
+	 sethi		%hi(THREAD_SIZE), %g3
+	add		%g7, %g3, %g7
+	cmp		%sp, %g7
+	blu,pn		%xcc, 1f
+2:	 sethi		%hi(softirq_stack), %g3
+	or		%g3, %lo(softirq_stack), %g3
+	ldx		[%g3 + %g1], %g7
+	cmp		%sp, %g7
+	bleu,pt		%xcc, 2f
+	 sethi		%hi(THREAD_SIZE), %g3
+	add		%g7, %g3, %g7
+	cmp		%sp, %g7
+	blu,pn		%xcc, 1f
+	 nop
 	/* If we are already on ovstack, don't hop onto it
 	 * again, we are already trying to output the stack overflow
 	 * message.
arch/sparc64/mm/init.c +11 -0
@@ -49,6 +49,7 @@
 #include <asm/sstate.h>
 #include <asm/mdesc.h>
 #include <asm/cpudata.h>
+#include <asm/irq.h>
 
 #define MAX_PHYS_ADDRESS	(1UL << 42UL)
 #define KPTE_BITMAP_CHUNK_SZ	(256UL * 1024UL * 1024UL)
@@ -1817,6 +1818,16 @@ void __init paging_init(void)
 	if (tlb_type == hypervisor)
 		sun4v_mdesc_init();
 
+	/* Once the OF device tree and MDESC have been setup, we know
+	 * the list of possible cpus.  Therefore we can allocate the
+	 * IRQ stacks.
+	 */
+	for_each_possible_cpu(i) {
+		/* XXX Use node local allocations... XXX */
+		softirq_stack[i] = __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+		hardirq_stack[i] = __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE));
+	}
+
 	/* Setup bootmem... */
 	last_valid_pfn = end_pfn = bootmem_init(phys_base);
 
include/asm-sparc64/irq.h +4 -0
@@ -90,4 +90,8 @@ static inline unsigned long get_softint(
 	return retval;
 }
 
+extern void *hardirq_stack[NR_CPUS];
+extern void *softirq_stack[NR_CPUS];
+#define __ARCH_HAS_DO_SOFTIRQ
+
 #endif
author
#51 lore raw

PATCH 51/60 sparc64: Handle stack trace attempts before irqstacks are setup.

In reply to Greg KH

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

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

[ Upstream commit 6f63e781eaf6a741fc65f773017154b20ed4ce3b ]

Things like lockdep can try to do stack backtraces before the irqstack blocks have been setup. So don't try to match their ranges so early on.

Also, remove unused variable in save_stack_trace().

---
 arch/sparc64/kernel/kstack.h     |   38 ++++++++++++++++++++------------------
 arch/sparc64/kernel/stacktrace.c |    3 +--
 2 files changed, 21 insertions(+), 20 deletions(-)
arch/sparc64/kernel/kstack.h +20 -18
@@ -15,15 +15,16 @@ static inline bool kstack_valid(struct t
 	    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
 		return true;
 
-	base = (unsigned long) hardirq_stack[tp->cpu];
-	if (sp >= base &&
-	    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
-		return true;
-	base = (unsigned long) softirq_stack[tp->cpu];
-	if (sp >= base &&
-	    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
-		return true;
-
+	if (hardirq_stack[tp->cpu]) {
+		base = (unsigned long) hardirq_stack[tp->cpu];
+		if (sp >= base &&
+		    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
+			return true;
+		base = (unsigned long) softirq_stack[tp->cpu];
+		if (sp >= base &&
+		    sp <= (base + THREAD_SIZE - sizeof(struct sparc_stackf)))
+			return true;
+	}
 	return false;
 }
 
@@ -37,15 +38,16 @@ static inline bool kstack_is_trap_frame(
 	    addr <= (base + THREAD_SIZE - sizeof(*regs)))
 		goto check_magic;
 
-	base = (unsigned long) hardirq_stack[tp->cpu];
-	if (addr >= base &&
-	    addr <= (base + THREAD_SIZE - sizeof(*regs)))
-		goto check_magic;
-	base = (unsigned long) softirq_stack[tp->cpu];
-	if (addr >= base &&
-	    addr <= (base + THREAD_SIZE - sizeof(*regs)))
-		goto check_magic;
-
+	if (hardirq_stack[tp->cpu]) {
+		base = (unsigned long) hardirq_stack[tp->cpu];
+		if (addr >= base &&
+		    addr <= (base + THREAD_SIZE - sizeof(*regs)))
+			goto check_magic;
+		base = (unsigned long) softirq_stack[tp->cpu];
+		if (addr >= base &&
+		    addr <= (base + THREAD_SIZE - sizeof(*regs)))
+			goto check_magic;
+	}
 	return false;
 
 check_magic:
arch/sparc64/kernel/stacktrace.c +1 -2
@@ -8,8 +8,8 @@
 
 void save_stack_trace(struct stack_trace *trace)
 {
-	unsigned long ksp, fp, thread_base;
 	struct thread_info *tp = task_thread_info(current);
+	unsigned long ksp, fp;
 
 	stack_trace_flush();
 
@@ -19,7 +19,6 @@ void save_stack_trace(struct stack_trace
 	);
 
 	fp = ksp + STACK_BIAS;
-	thread_base = (unsigned long) tp;
 	do {
 		struct sparc_stackf *sf;
 		struct pt_regs *regs;
author
#52 lore raw

PATCH 52/60 x86: fix spin_is_contended()

In reply to Greg KH

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

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

commit 7bc069c6bc4ede519a7116be1b9e149a1dbf787a upstream

The masked difference is what needs to be compared against 1, rather than the difference of masked values (which can be negative).

---
 include/asm-x86/spinlock.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/asm-x86/spinlock.h +2 -2
@@ -65,7 +65,7 @@ static inline int __raw_spin_is_contende
 {
 	int tmp = ACCESS_ONCE(lock->slock);
 
-	return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
+	return (((tmp >> 8) - tmp) & 0xff) > 1;
 }
 
 static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
@@ -129,7 +129,7 @@ static inline int __raw_spin_is_contende
 {
 	int tmp = ACCESS_ONCE(lock->slock);
 
-	return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
+	return (((tmp >> 16) - tmp) & 0xffff) > 1;
 }
 
 static __always_inline void __raw_spin_lock(raw_spinlock_t *lock)
author
#53 lore raw

PATCH 53/60 x86: fix setup code crashes on my old 486 box

In reply to Greg KH

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

------------------
From: Joerg Roedel <[email protected]>

commit 7b27718bdb1b70166383dec91391df5534d449ee upstream

yesterday I tried to reactivate my old 486 box and wanted to install a current Linux with latest kernel on it. But it turned out that the latest kernel does not boot because the machine crashes early in the setup code.

After some debugging it turned out that the problem is the query_ist() function. If this interrupt with that function is called the machine simply locks up. It looks like a BIOS bug. Looking for a workaround for this problem I wrote the attached patch. It checks for the CPUID instruction and if it is not implemented it does not call the speedstep BIOS function. As far as I know speedstep should be available since some Pentium earliest.

Alan Cox observed that it's available since the Pentium II, so cpuid levels 4 and 5 can be excluded altogether.

H. Peter Anvin cleaned up the code some more:

Quoted 3 lines

Right in concept, but I dislike the implementation (duplication of the CPU detect code we already have). Could you try this patch and see if it works for you?

which, with a small modification to fix a build error with it the resulting kernel boots on my machine.

---
 arch/x86/boot/boot.h     |    8 ++++++++
 arch/x86/boot/cpucheck.c |    8 +-------
 arch/x86/boot/main.c     |    4 ++++
 3 files changed, 13 insertions(+), 7 deletions(-)
arch/x86/boot/boot.h +8 -0
@@ -25,6 +25,8 @@
 #include <asm/boot.h>
 #include <asm/setup.h>
 
+#define NCAPINTS   8
+
 /* Useful macros */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
@@ -242,6 +244,12 @@ int cmdline_find_option(const char *opti
 int cmdline_find_option_bool(const char *option);
 
 /* cpu.c, cpucheck.c */
+struct cpu_features {
+	int level;		/* Family, or 64 for x86-64 */
+	int model;
+	u32 flags[NCAPINTS];
+};
+extern struct cpu_features cpu;
 int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
 int validate_cpu(void);
 
arch/x86/boot/cpucheck.c +1 -7
@@ -30,13 +30,7 @@
 #include <asm/required-features.h>
 #include <asm/msr-index.h>
 
-struct cpu_features {
-	int level;		/* Family, or 64 for x86-64 */
-	int model;
-	u32 flags[NCAPINTS];
-};
-
-static struct cpu_features cpu;
+struct cpu_features cpu;
 static u32 cpu_vendor[3];
 static u32 err_flags[NCAPINTS];
 
arch/x86/boot/main.c +4 -0
@@ -73,6 +73,10 @@ static void keyboard_set_repeat(void)
  */
 static void query_ist(void)
 {
+	/* Some 486 BIOSes apparently crash on this call */
+	if (cpu.level < 6)
+		return;
+
 	asm("int $0x15"
 	    : "=a" (boot_params.ist_info.signature),
 	      "=b" (boot_params.ist_info.command),
reviewer Acked-by on v1 53/60
#54 lore raw

Re: [patch 53/60] x86: fix setup code crashes on my old 486 box

Greg KH wrote:
2.6.26-stable review patch. If anyone has any objections, please let us know.

No objection here.

author
#55 lore raw

PATCH 54/60 qla2xxx: Add dev_loss_tmo_callbk/terminate_rport_io callback support.

In reply to Greg KH

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

------------------
From: Seokmann Ju <[email protected]>

[ Upstream commit 5f3a9a207f1fccde476dd31b4c63ead2967d934f ]

---
 drivers/scsi/qla2xxx/qla_attr.c |   31 +++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_def.h  |    1 
 drivers/scsi/qla2xxx/qla_gbl.h  |    2 +
 drivers/scsi/qla2xxx/qla_init.c |   16 +++---------
 drivers/scsi/qla2xxx/qla_os.c   |   53 ++++++++++++++++++++++++++++++----------
 5 files changed, 78 insertions(+), 25 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +31 -0
@@ -994,6 +994,33 @@ qla2x00_set_rport_loss_tmo(struct fc_rpo
 	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
 }
 
+static void
+qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
+{
+	struct Scsi_Host *host = rport_to_shost(rport);
+	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+	qla2x00_abort_fcport_cmds(fcport);
+
+	/*
+	 * Transport has effectively 'deleted' the rport, clear
+	 * all local references.
+	 */
+	spin_lock_irq(host->host_lock);
+	fcport->rport = NULL;
+	*((fc_port_t **)rport->dd_data) = NULL;
+	spin_unlock_irq(host->host_lock);
+}
+
+static void
+qla2x00_terminate_rport_io(struct fc_rport *rport)
+{
+	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+	qla2x00_abort_fcport_cmds(fcport);
+	scsi_target_unblock(&rport->dev);
+}
+
 static int
 qla2x00_issue_lip(struct Scsi_Host *shost)
 {
@@ -1253,6 +1280,8 @@ struct fc_function_template qla2xxx_tran
 	.show_rport_dev_loss_tmo = 1,
 
 	.issue_fc_host_lip = qla2x00_issue_lip,
+	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
 
 	.vport_create = qla24xx_vport_create,
@@ -1296,6 +1325,8 @@ struct fc_function_template qla2xxx_tran
 	.show_rport_dev_loss_tmo = 1,
 
 	.issue_fc_host_lip = qla2x00_issue_lip,
+	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
 };
 
drivers/scsi/qla2xxx/qla_def.h +0 -1
@@ -1544,7 +1544,6 @@ typedef struct fc_port {
 	int login_retry;
 	atomic_t port_down_timer;
 
-	spinlock_t rport_lock;
 	struct fc_rport *rport, *drport;
 	u32 supported_classes;
 
drivers/scsi/qla2xxx/qla_gbl.h +2 -0
@@ -71,6 +71,8 @@ extern int qla2x00_post_aen_work(struct 
 extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
     uint16_t, uint16_t);
 
+extern void qla2x00_abort_fcport_cmds(fc_port_t *);
+
 /*
  * Global Functions in qla_mid.c source file.
  */
drivers/scsi/qla2xxx/qla_init.c +5 -11
@@ -1864,12 +1864,11 @@ qla2x00_rport_del(void *data)
 {
 	fc_port_t *fcport = data;
 	struct fc_rport *rport;
-	unsigned long flags;
 
-	spin_lock_irqsave(&fcport->rport_lock, flags);
+	spin_lock_irq(fcport->ha->host->host_lock);
 	rport = fcport->drport;
 	fcport->drport = NULL;
-	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+	spin_unlock_irq(fcport->ha->host->host_lock);
 	if (rport)
 		fc_remote_port_delete(rport);
 }
@@ -1898,7 +1897,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha
 	atomic_set(&fcport->state, FCS_UNCONFIGURED);
 	fcport->flags = FCF_RLC_SUPPORT;
 	fcport->supported_classes = FC_COS_UNSPECIFIED;
-	spin_lock_init(&fcport->rport_lock);
 
 	return fcport;
 }
@@ -2243,28 +2241,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 {
 	struct fc_rport_identifiers rport_ids;
 	struct fc_rport *rport;
-	unsigned long flags;
 
 	if (fcport->drport)
 		qla2x00_rport_del(fcport);
-	if (fcport->rport)
-		return;
 
 	rport_ids.node_name = wwn_to_u64(fcport->node_name);
 	rport_ids.port_name = wwn_to_u64(fcport->port_name);
 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+	fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
 	if (!rport) {
 		qla_printk(KERN_WARNING, ha,
 		    "Unable to allocate fc remote port!\n");
 		return;
 	}
-	spin_lock_irqsave(&fcport->rport_lock, flags);
-	fcport->rport = rport;
+	spin_lock_irq(fcport->ha->host->host_lock);
 	*((fc_port_t **)rport->dd_data) = fcport;
-	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+	spin_unlock_irq(fcport->ha->host->host_lock);
 
 	rport->supported_classes = fcport->supported_classes;
 
drivers/scsi/qla2xxx/qla_os.c +40 -13

86 lines not on this page · raw message

author
#56 lore raw

PATCH 55/60 qla2xxx: Set an rports dev_loss_tmo value in a consistent manner.

In reply to Greg KH

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

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

[ Upstream commit 85821c906cf3563a00a3d98fa380a2581a7a5ff1 ]

As there's no point in adding a fixed-fudge value (originally 5 seconds), honor the user settings only. We also remove the driver's dead-callback get_rport_dev_loss_tmo function (qla2x00_get_rport_loss_tmo()).

---
 drivers/scsi/qla2xxx/qla_attr.c |   20 ++------------------
 drivers/scsi/qla2xxx/qla_os.c   |    2 +-
 2 files changed, 3 insertions(+), 19 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +2 -18
@@ -972,26 +972,12 @@ qla2x00_get_starget_port_id(struct scsi_
 }
 
 static void
-qla2x00_get_rport_loss_tmo(struct fc_rport *rport)
-{
-	struct Scsi_Host *host = rport_to_shost(rport);
-	scsi_qla_host_t *ha = shost_priv(host);
-
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
-}
-
-static void
 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
 {
-	struct Scsi_Host *host = rport_to_shost(rport);
-	scsi_qla_host_t *ha = shost_priv(host);
-
 	if (timeout)
-		ha->port_down_retry_count = timeout;
+		rport->dev_loss_tmo = timeout;
 	else
-		ha->port_down_retry_count = 1;
-
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+		rport->dev_loss_tmo = 1;
 }
 
 static void
@@ -1275,7 +1261,6 @@ struct fc_function_template qla2xxx_tran
 	.get_starget_port_id  = qla2x00_get_starget_port_id,
 	.show_starget_port_id = 1,
 
-	.get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
 	.show_rport_dev_loss_tmo = 1,
 
@@ -1320,7 +1305,6 @@ struct fc_function_template qla2xxx_tran
 	.get_starget_port_id  = qla2x00_get_starget_port_id,
 	.show_starget_port_id = 1,
 
-	.get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
 	.show_rport_dev_loss_tmo = 1,
 
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -1107,7 +1107,7 @@ qla2xxx_slave_configure(struct scsi_devi
 	else
 		scsi_deactivate_tcq(sdev, ha->max_q_depth);
 
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+	rport->dev_loss_tmo = ha->port_down_retry_count;
 
 	return 0;
 }
author
#57 lore raw

PATCH 56/60 usb-storage: revert DMA-alignment change for Wireless USB

In reply to Greg KH

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

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

commit f756cbd458ab71c996a069cb3928fb1e2d7cd9cc upstream.

This patch (as1110) reverts an earlier patch meant to help with Wireless USB host controllers. These controllers can have bulk maxpacket values larger than 512, which puts unusual constraints on the sizes of scatter-gather list elements. However it turns out that the block layer does not provide the support we need to enforce these constraints; merely changing the DMA alignment mask doesn't help. Hence there's no reason to keep the original patch. The Wireless USB problem will have to be solved a different way.

In addition, there is a reason to get rid of the earlier patch. By dereferencing a pointer stored in the ep_in array of struct usb_device, the current code risks an invalid memory access when it runs concurrently with device removal. The members of that array are cleared before the driver's disconnect method is called, so it should not try to use them.

---
 drivers/usb/storage/scsiglue.c |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)
drivers/usb/storage/scsiglue.c +15 -10
@@ -73,7 +73,6 @@ static const char* host_info(struct Scsi
 static int slave_alloc (struct scsi_device *sdev)
 {
 	struct us_data *us = host_to_us(sdev->host);
-	struct usb_host_endpoint *bulk_in_ep;
 
 	/*
 	 * Set the INQUIRY transfer length to 36.  We don't use any of
@@ -82,16 +81,22 @@ static int slave_alloc (struct scsi_devi
 	 */
 	sdev->inquiry_len = 36;
 
-	/* Scatter-gather buffers (all but the last) must have a length
-	 * divisible by the bulk maxpacket size.  Otherwise a data packet
-	 * would end up being short, causing a premature end to the data
-	 * transfer.  We'll use the maxpacket value of the bulk-IN pipe
-	 * to set the SCSI device queue's DMA alignment mask.
+	/* USB has unusual DMA-alignment requirements: Although the
+	 * starting address of each scatter-gather element doesn't matter,
+	 * the length of each element except the last must be divisible
+	 * by the Bulk maxpacket value.  There's currently no way to
+	 * express this by block-layer constraints, so we'll cop out
+	 * and simply require addresses to be aligned at 512-byte
+	 * boundaries.  This is okay since most block I/O involves
+	 * hardware sectors that are multiples of 512 bytes in length,
+	 * and since host controllers up through USB 2.0 have maxpacket
+	 * values no larger than 512.
+	 *
+	 * But it doesn't suffice for Wireless USB, where Bulk maxpacket
+	 * values can be as large as 2048.  To make that work properly
+	 * will require changes to the block layer.
 	 */
-	bulk_in_ep = us->pusb_dev->ep_in[usb_pipeendpoint(us->recv_bulk_pipe)];
-	blk_queue_update_dma_alignment(sdev->request_queue,
-			le16_to_cpu(bulk_in_ep->desc.wMaxPacketSize) - 1);
-			/* wMaxPacketSize must be a power of 2 */
+	blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
 
 	/*
 	 * The UFI spec treates the Peripheral Qualifier bits in an
author
#58 lore raw

PATCH 57/60 usb-storage: automatically recognize bad residues

In reply to Greg KH

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

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

commit 59f4ff2ecff4cef36378928cec891785b402e80c upstream

This patch (as1119b) will help to reduce the clutter of usb-storage's unusual_devs file by automatically detecting some devices that need the IGNORE_RESIDUE flag. The idea is that devices should never return a non-zero residue for an INQUIRY or a READ CAPACITY command unless they failed to transfer all the requested data. So if one of these commands transfers a standard amount of data but there is a positive residue, we know that the residue is bogus and we can set the flag.

This fixes the problems reported in Bugzilla #11125.

---
 drivers/usb/storage/transport.c |   17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)
drivers/usb/storage/transport.c +15 -2
@@ -1034,8 +1034,21 @@ int usb_stor_Bulk_transport(struct scsi_
 
 	/* try to compute the actual residue, based on how much data
 	 * was really transferred and what the device tells us */
-	if (residue) {
-		if (!(us->flags & US_FL_IGNORE_RESIDUE)) {
+	if (residue && !(us->flags & US_FL_IGNORE_RESIDUE)) {
+
+		/* Heuristically detect devices that generate bogus residues
+		 * by seeing what happens with INQUIRY and READ CAPACITY
+		 * commands.
+		 */
+		if (bcs->Status == US_BULK_STAT_OK &&
+				scsi_get_resid(srb) == 0 &&
+					((srb->cmnd[0] == INQUIRY &&
+						transfer_length == 36) ||
+					(srb->cmnd[0] == READ_CAPACITY &&
+						transfer_length == 8))) {
+			us->flags |= US_FL_IGNORE_RESIDUE;
+
+		} else {
 			residue = min(residue, transfer_length);
 			scsi_set_resid(srb, max(scsi_get_resid(srb),
 			                                       (int) residue));
author
#59 lore raw

PATCH 58/60 CIFS: properly account for new user= field in SPNEGO upcall string allocation

In reply to Greg KH

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

------------------
From: Jeff Layton <[email protected]>

commit 66b8bd3c405389213de1d6ba6c2565990f62004f upstream

[CIFS] properly account for new user= field in SPNEGO upcall string allocation

...it doesn't look like it's being accounted for at the moment. Also try to reorganize the calculation to make it a little more evident what each piece means.

This should probably go to the stable series as well...

---
 fs/cifs/cifs_spnego.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)
fs/cifs/cifs_spnego.c +11 -7
@@ -66,8 +66,8 @@ struct key_type cifs_spnego_key_type = {
 	.describe	= user_describe,
 };
 
-#define MAX_VER_STR_LEN   9 /* length of longest version string e.g.
-				strlen(";ver=0xFF") */
+#define MAX_VER_STR_LEN   8 /* length of longest version string e.g.
+				strlen("ver=0xFF") */
 #define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg
 			       in future could have strlen(";sec=ntlmsspi") */
 #define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
@@ -81,11 +81,15 @@ cifs_get_spnego_key(struct cifsSesInfo *
 	struct key *spnego_key;
 	const char *hostname = server->hostname;
 
-	/* BB: come up with better scheme for determining length */
-	/* length of fields (with semicolons): ver=0xyz ipv4= ipaddress host=
-	   hostname sec=mechanism uid=0x uid */
-	desc_len = MAX_VER_STR_LEN + 5 + MAX_IPV6_ADDR_LEN + 1 + 6 +
-		  strlen(hostname) + MAX_MECH_STR_LEN + 8 + (sizeof(uid_t) * 2);
+	/* length of fields (with semicolons): ver=0xyz ip4=ipaddress
+	   host=hostname sec=mechanism uid=0xFF user=username */
+	desc_len = MAX_VER_STR_LEN +
+		   6 /* len of "host=" */ + strlen(hostname) +
+		   5 /* len of ";ipv4=" */ + MAX_IPV6_ADDR_LEN +
+		   MAX_MECH_STR_LEN +
+		   7 /* len of ";uid=0x" */ + (sizeof(uid_t) * 2) +
+		   6 /* len of ";user=" */ + strlen(sesInfo->userName) + 1;
+
 	spnego_key = ERR_PTR(-ENOMEM);
 	description = kzalloc(desc_len, GFP_KERNEL);
 	if (description == NULL)
author
#60 lore raw

PATCH 59/60 PCI: Limit VPD length for Broadcom 5708S

In reply to Greg KH

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

------------------
From: Dean Hildebrand <[email protected]>

commit 35405f256de924be56ea5edaca4cdc627f1bb0f8 upstream

BCM5706S wont work correctly unless VPD length truncated to 128

---
 drivers/pci/quirks.c |    7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/pci/quirks.c +6 -1
@@ -1683,9 +1683,14 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_VI
  */
 static void __devinit quirk_brcm_570x_limit_vpd(struct pci_dev *dev)
 {
-	/*  Only disable the VPD capability for 5706, 5708, and 5709 rev. A */
+	/*
+	 * Only disable the VPD capability for 5706, 5706S, 5708,
+	 * 5708S and 5709 rev. A
+	 */
 	if ((dev->device == PCI_DEVICE_ID_NX2_5706) ||
+	    (dev->device == PCI_DEVICE_ID_NX2_5706S) ||
 	    (dev->device == PCI_DEVICE_ID_NX2_5708) ||
+  	    (dev->device == PCI_DEVICE_ID_NX2_5708S) ||
 	    ((dev->device == PCI_DEVICE_ID_NX2_5709) &&
 	     (dev->revision & 0xf0) == 0x0)) {
 		if (dev->vpd)
author
#61 lore raw

PATCH 60/60 crypto: padlock - fix VIA PadLock instruction usage with irq_ts_save/restore()

In reply to Greg KH

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

------------------
From: Suresh Siddha <[email protected]>

crypto: padlock - fix VIA PadLock instruction usage with irq_ts_save/restore()

[ Upstream commit: e49140120c88eb99db1a9172d9ac224c0f2bbdd2 ]

Wolfgang Walter reported this oops on his via C3 using padlock for AES-encryption:

##################################################################

BUG: unable to handle kernel NULL pointer dereference at 000001f0
IP: [<c01028c5>] __switch_to+0x30/0x117
*pde = 00000000
Oops: 0002 [#1] PREEMPT
Modules linked in:

Pid: 2071, comm: sleep Not tainted (2.6.26 #11)
EIP: 0060:[<c01028c5>] EFLAGS: 00010002 CPU: 0
EIP is at __switch_to+0x30/0x117
EAX: 00000000 EBX: c0493300 ECX: dc48dd00 EDX: c0493300
ESI: dc48dd00 EDI: c0493530 EBP: c04cff8c ESP: c04cff7c
DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068
Process sleep (pid: 2071, ti=c04ce000 task=dc48dd00 task.ti=d2fe6000)

Stack: dc48df30 c0493300 00000000 00000000 d2fe7f44 c03b5b43 c04cffc8 00000046
   c0131856 0000005a dc472d3c c0493300 c0493470 d983ae00 00002696 00000000
   c0239f54 00000000 c04c4000 c04cffd8 c01025fe c04f3740 00049800 c04cffe0
Call Trace:
[<c03b5b43>] ? schedule+0x285/0x2ff
[<c0131856>] ? pm_qos_requirement+0x3c/0x53
[<c0239f54>] ? acpi_processor_idle+0x0/0x434
[<c01025fe>] ? cpu_idle+0x73/0x7f
[<c03a4dcd>] ? rest_init+0x61/0x63
=======================

Wolfgang also found out that adding kernel_fpu_begin() and kernel_fpu_end() around the padlock instructions fix the oops.

Suresh wrote:

These padlock instructions though don't use/touch SSE registers, but it behaves similar to other SSE instructions. For example, it might cause DNA faults when cr0.ts is set. While this is a spurious DNA trap, it might cause oops with the recent fpu code changes.

This is the code sequence that is probably causing this problem:

a) new app is getting exec'd and it is somewhere in between start_thread() and flush_old_exec() in the load_xyz_binary()

b) At pont "a", task's fpu state (like TS_USEDFPU, used_math() etc) is cleared.

c) Now we get an interrupt/softirq which starts using these encrypt/decrypt routines in the network stack. This generates a math fault (as cr0.ts is '1') which sets TS_USEDFPU and restores the math that is in the task's xstate.

d) Return to exec code path, which does start_thread() which does free_thread_xstate() and sets xstate pointer to NULL while the TS_USEDFPU is still set.

e) At the next context switch from the new exec'd task to another task, we have a scenarios where TS_USEDFPU is set but xstate pointer is null. This can cause an oops during unlazy_fpu() in __switch_to()

Now:

1) This should happen with or with out pre-emption. Viro also encountered similar problem with out CONFIG_PREEMPT.

2) kernel_fpu_begin() and kernel_fpu_end() will fix this problem, because kernel_fpu_begin() will manually do a clts() and won't run in to the situation of setting TS_USEDFPU in step "c" above.

3) This was working before the fpu changes, because its a spurious math fault which doesn't corrupt any fpu/sse registers and the task's math state was always in an allocated state.

With out the recent lazy fpu allocation changes, while we don't see oops, there is a possible race still present in older kernels(for example, while kernel is using kernel_fpu_begin() in some optimized clear/copy page and an interrupt/softirq happens which uses these padlock instructions generating DNA fault).

This is the failing scenario that existed even before the lazy fpu allocation changes:

0. CPU's TS flag is set

1. kernel using FPU in some optimized copy routine and while doing kernel_fpu_begin() takes an interrupt just before doing clts()

2. Takes an interrupt and ipsec uses padlock instruction. And we take a DNA fault as TS flag is still set.

3. We handle the DNA fault and set TS_USEDFPU and clear cr0.ts

4. We complete the padlock routine

5. Go back to step-1, which resumes clts() in kernel_fpu_begin(), finishes the optimized copy routine and does kernel_fpu_end(). At this point, we have cr0.ts again set to '1' but the task's TS_USEFPU is stilll set and not cleared.

6. Now kernel resumes its user operation. And at the next context switch, kernel sees it has do a FP save as TS_USEDFPU is still set and then will do a unlazy_fpu() in __switch_to(). unlazy_fpu() will take a DNA fault, as cr0.ts is '1' and now, because we are in __switch_to(), math_state_restore() will get confused and will restore the next task's FP state and will save it in prev tasks's FP state. Remember, in __switch_to() we are already on the stack of the next task but take a DNA fault for the prev task.

This causes the fpu leakage.

Fix the padlock instruction usage by calling them inside the context of new routines irq_ts_save/restore(), which clear/restore cr0.ts manually in the interrupt context. This will not generate spurious DNA in the context of the interrupt which will fix the oops encountered and the possible FPU leakage issue.

---
 drivers/char/hw_random/via-rng.c |    8 ++++++++
 drivers/crypto/padlock-aes.c     |   28 +++++++++++++++++++++++++++-
 drivers/crypto/padlock-sha.c     |    9 +++++++++
 include/asm-x86/i387.h           |   32 ++++++++++++++++++++++++++++++++
 4 files changed, 76 insertions(+), 1 deletion(-)
drivers/char/hw_random/via-rng.c +8 -0
@@ -31,6 +31,7 @@
 #include <asm/io.h>
 #include <asm/msr.h>
 #include <asm/cpufeature.h>
+#include <asm/i387.h>
 
 
 #define PFX	KBUILD_MODNAME ": "
@@ -67,16 +68,23 @@ enum {
  * Another possible performance boost may come from simply buffering
  * until we have 4 bytes, thus returning a u32 at a time,
  * instead of the current u8-at-a-time.
+ *
+ * Padlock instructions can generate a spurious DNA fault, so
+ * we have to call them in the context of irq_ts_save/restore()
  */
 
 static inline u32 xstore(u32 *addr, u32 edx_in)
 {
 	u32 eax_out;
+	int ts_state;
+
+	ts_state = irq_ts_save();
 
 	asm(".byte 0x0F,0xA7,0xC0 /* xstore %%edi (addr=%0) */"
 		:"=m"(*addr), "=a"(eax_out)
 		:"D"(addr), "d"(edx_in));
 
+	irq_ts_restore(ts_state);
 	return eax_out;
 }
 
drivers/crypto/padlock-aes.c +27 -1
@@ -16,6 +16,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <asm/byteorder.h>
+#include <asm/i387.h>
 #include "padlock.h"
 
 /* Control word. */
@@ -141,6 +142,12 @@ static inline void padlock_reset_key(voi
 	asm volatile ("pushfl; popfl");
 }
 
+/*
+ * While the padlock instructions don't use FP/SSE registers, they
+ * generate a spurious DNA fault when cr0.ts is '1'. These instructions
+ * should be used only inside the irq_ts_save/restore() context
+ */
+
 static inline void padlock_xcrypt(const u8 *input, u8 *output, void *key,
 				  void *control_word)
 {
@@ -205,15 +212,23 @@ static inline u8 *padlock_xcrypt_cbc(con
 static void aes_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct aes_ctx *ctx = aes_ctx(tfm);
+	int ts_state;
 	padlock_reset_key();
+
+	ts_state = irq_ts_save();
 	aes_crypt(in, out, ctx->E, &ctx->cword.encrypt);
+	irq_ts_restore(ts_state);
 }
 
 static void aes_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
 	struct aes_ctx *ctx = aes_ctx(tfm);
+	int ts_state;
 	padlock_reset_key();
+
+	ts_state = irq_ts_save();
 	aes_crypt(in, out, ctx->D, &ctx->cword.decrypt);
+	irq_ts_restore(ts_state);
 }
 
 static struct crypto_alg aes_alg = {
@@ -244,12 +259,14 @@ static int ecb_aes_encrypt(struct blkcip
 	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	int err;
+	int ts_state;
 
 	padlock_reset_key();
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
+	ts_state = irq_ts_save();
 	while ((nbytes = walk.nbytes)) {
 		padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
 				   ctx->E, &ctx->cword.encrypt,
@@ -257,6 +274,7 @@ static int ecb_aes_encrypt(struct blkcip
 		nbytes &= AES_BLOCK_SIZE - 1;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
+	irq_ts_restore(ts_state);
 
 	return err;
 }
@@ -268,12 +286,14 @@ static int ecb_aes_decrypt(struct blkcip
 	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	int err;
+	int ts_state;
 
 	padlock_reset_key();
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
+	ts_state = irq_ts_save();
 	while ((nbytes = walk.nbytes)) {
 		padlock_xcrypt_ecb(walk.src.virt.addr, walk.dst.virt.addr,
 				   ctx->D, &ctx->cword.decrypt,
@@ -281,7 +301,7 @@ static int ecb_aes_decrypt(struct blkcip
 		nbytes &= AES_BLOCK_SIZE - 1;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
-
+	irq_ts_restore(ts_state);
 	return err;
 }
 
@@ -314,12 +334,14 @@ static int cbc_aes_encrypt(struct blkcip
 	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	int err;
+	int ts_state;
 
 	padlock_reset_key();
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
+	ts_state = irq_ts_save();
 	while ((nbytes = walk.nbytes)) {
 		u8 *iv = padlock_xcrypt_cbc(walk.src.virt.addr,
 					    walk.dst.virt.addr, ctx->E,
@@ -329,6 +351,7 @@ static int cbc_aes_encrypt(struct blkcip
 		nbytes &= AES_BLOCK_SIZE - 1;
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
+	irq_ts_restore(ts_state);
 
 	return err;
 }
@@ -340,12 +363,14 @@ static int cbc_aes_decrypt(struct blkcip
 	struct aes_ctx *ctx = blk_aes_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 	int err;
+	int ts_state;
 
 	padlock_reset_key();
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
 	err = blkcipher_walk_virt(desc, &walk);
 
+	ts_state = irq_ts_save();
 	while ((nbytes = walk.nbytes)) {
 		padlock_xcrypt_cbc(walk.src.virt.addr, walk.dst.virt.addr,
 				   ctx->D, walk.iv, &ctx->cword.decrypt,
@@ -354,6 +379,7 @@ static int cbc_aes_decrypt(struct blkcip
 		err = blkcipher_walk_done(desc, &walk, nbytes);
 	}
 
+	irq_ts_restore(ts_state);
 	return err;
 }
 
drivers/crypto/padlock-sha.c +9 -0
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/scatterlist.h>
+#include <asm/i387.h>
 #include "padlock.h"
 
 #define SHA1_DEFAULT_FALLBACK	"sha1-generic"
@@ -102,6 +103,7 @@ static void padlock_do_sha1(const char *
 	 *     PadLock microcode needs it that big. */
 	char buf[128+16];
 	char *result = NEAREST_ALIGNED(buf);
+	int ts_state;
 
 	((uint32_t *)result)[0] = SHA1_H0;
 	((uint32_t *)result)[1] = SHA1_H1;
@@ -109,9 +111,12 @@ static void padlock_do_sha1(const char *
 	((uint32_t *)result)[3] = SHA1_H3;
 	((uint32_t *)result)[4] = SHA1_H4;
  
+	/* prevent taking the spurious DNA fault with padlock. */
+	ts_state = irq_ts_save();
 	asm volatile (".byte 0xf3,0x0f,0xa6,0xc8" /* rep xsha1 */
 		      : "+S"(in), "+D"(result)
 		      : "c"(count), "a"(0));
+	irq_ts_restore(ts_state);
 
 	padlock_output_block((uint32_t *)result, (uint32_t *)out, 5);
 }
@@ -123,6 +128,7 @@ static void padlock_do_sha256(const char
 	 *     PadLock microcode needs it that big. */
 	char buf[128+16];
 	char *result = NEAREST_ALIGNED(buf);
+	int ts_state;
 
 	((uint32_t *)result)[0] = SHA256_H0;
 	((uint32_t *)result)[1] = SHA256_H1;
@@ -133,9 +139,12 @@ static void padlock_do_sha256(const char
 	((uint32_t *)result)[6] = SHA256_H6;
 	((uint32_t *)result)[7] = SHA256_H7;
 
+	/* prevent taking the spurious DNA fault with padlock. */
+	ts_state = irq_ts_save();
 	asm volatile (".byte 0xf3,0x0f,0xa6,0xd0" /* rep xsha256 */
 		      : "+S"(in), "+D"(result)
 		      : "c"(count), "a"(0));
+	irq_ts_restore(ts_state);
 
 	padlock_output_block((uint32_t *)result, (uint32_t *)out, 8);
 }
include/asm-x86/i387.h +32 -0
@@ -13,6 +13,7 @@
 #include <linux/sched.h>
 #include <linux/kernel_stat.h>
 #include <linux/regset.h>
+#include <linux/hardirq.h>
 #include <asm/asm.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
@@ -290,6 +291,37 @@ static inline void kernel_fpu_end(void)
 	preempt_enable();
 }
 
+/*
+ * Some instructions like VIA's padlock instructions generate a spurious
+ * DNA fault but don't modify SSE registers. And these instructions
+ * get used from interrupt context aswell. To prevent these kernel instructions
+ * in interrupt context interact wrongly with other user/kernel fpu usage, we
+ * should use them only in the context of irq_ts_save/restore()
+ */
+static inline int irq_ts_save(void)
+{
+	/*
+	 * If we are in process context, we are ok to take a spurious DNA fault.
+	 * Otherwise, doing clts() in process context require pre-emption to
+	 * be disabled or some heavy lifting like kernel_fpu_begin()
+	 */
+	if (!in_interrupt())
+		return 0;
+
+	if (read_cr0() & X86_CR0_TS) {
+		clts();
+		return 1;
+	}
+
+	return 0;
+}
+
+static inline void irq_ts_restore(int TS_state)
+{
+	if (TS_state)
+		stts();
+}
+
 #ifdef CONFIG_X86_64
 
 static inline void save_init_fpu(struct task_struct *tsk)
author
#62 lore raw

cover 2.6.25-stable review

This is the start of the stable review cycle for the 2.6.25.16 release. There are 49 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, August 20, 17:00:00 UTC. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.25.16-rc1.gz

and the diffstat can be found below.

thanks,

the -stable release team

 Makefile                                 |    2 -
 arch/sparc64/kernel/signal.c             |    6 ++-
 arch/um/Makefile                         |    1 
 arch/um/Makefile-i386                    |    7 +++
 arch/um/Makefile-x86_64                  |    3 +
 arch/um/drivers/chan_user.c              |    1 
 arch/um/drivers/cow_sys.h                |    2 -
 arch/um/drivers/daemon_user.c            |    4 +-
 arch/um/drivers/fd.c                     |    2 -
 arch/um/drivers/mcast_user.c             |    3 +
 arch/um/drivers/net_user.c               |    2 -
 arch/um/drivers/pcap_user.c              |    2 -
 arch/um/drivers/port_user.c              |    2 -
 arch/um/drivers/pty.c                    |    2 -
 arch/um/drivers/slip_user.c              |    2 -
 arch/um/drivers/tty.c                    |    2 -
 arch/um/drivers/xterm.c                  |    2 -
 arch/um/include/init.h                   |    8 ++++
 arch/um/include/os.h                     |    2 -
 arch/um/include/process.h                |    4 +-
 arch/um/include/um_malloc.h              |    9 +---
 arch/um/kernel/mem.c                     |    5 ++
 arch/um/kernel/time.c                    |    4 +-
 arch/um/kernel/um_arch.c                 |    7 ++-
 arch/um/os-Linux/drivers/ethertap_user.c |    4 +-
 arch/um/os-Linux/helper.c                |    5 +-
 arch/um/os-Linux/main.c                  |    2 -
 arch/um/os-Linux/sigio.c                 |    4 +-
 arch/um/os-Linux/signal.c                |    1 
 arch/um/os-Linux/skas/process.c          |    2 -
 arch/um/os-Linux/start_up.c              |   25 ++++++++----
 arch/um/os-Linux/sys-i386/task_size.c    |   38 ++++++++++++++-----
 arch/um/os-Linux/sys-x86_64/task_size.c  |    2 -
 arch/um/os-Linux/time.c                  |   61 ++++++++++++++++++++++++++++---
 arch/um/sys-x86_64/ksyms.c               |    5 ++
 arch/x86/boot/boot.h                     |    8 ++++
 arch/x86/boot/cpucheck.c                 |    8 ----
 arch/x86/boot/main.c                     |    4 ++
 block/scsi_ioctl.c                       |    2 -
 drivers/i2c/i2c-core.c                   |    4 +-
 drivers/ide/ide-cd.c                     |   18 +++++----
 drivers/misc/acer-wmi.c                  |   19 +++++++++
 drivers/net/r8169.c                      |    6 ++-
 drivers/scsi/hptiop.c                    |    7 +++
 drivers/scsi/qla2xxx/qla_attr.c          |   43 ++++++++++++++-------
 drivers/scsi/qla2xxx/qla_def.h           |    1 
 drivers/scsi/qla2xxx/qla_gbl.h           |    2 +
 drivers/scsi/qla2xxx/qla_init.c          |   16 ++------
 drivers/scsi/qla2xxx/qla_os.c            |   55 ++++++++++++++++++++-------
 drivers/scsi/scsi_transport_spi.c        |    8 ++--
 drivers/scsi/ses.c                       |   18 +++++++--
 drivers/usb/serial/ftdi_sio.c            |    5 ++
 drivers/usb/serial/ftdi_sio.h            |    6 +++
 drivers/usb/serial/pl2303.c              |    1 
 drivers/usb/serial/pl2303.h              |    4 --
 drivers/usb/serial/usb-serial.c          |    7 +--
 drivers/usb/storage/unusual_devs.h       |   18 ++++++++-
 drivers/video/aty/radeon_accel.c         |   12 +++++-
 drivers/video/matrox/matroxfb_maven.c    |    2 -
 fs/cifs/asn1.c                           |    2 -
 fs/cifs/cifsfs.c                         |    2 +
 fs/cifs/inode.c                          |    1 
 include/asm-sparc64/futex.h              |    2 -
 include/asm-x86/spinlock.h               |    4 +-
 include/linux/usb/serial.h               |    3 +
 include/video/radeon.h                   |    9 +++-
 kernel/posix-timers.c                    |   19 +++++++--
 kernel/relay.c                           |   12 +++++-
 kernel/signal.c                          |    1 
 lib/random32.c                           |   48 +++++++++++++-----------
 mm/memory.c                              |   16 ++++++--
 mm/mlock.c                               |    2 -
 net/dccp/proto.c                         |    5 ++
 net/ipv4/ipvs/ip_vs_est.c                |    7 ++-
 net/ipv4/netfilter/nf_nat_snmp_basic.c   |    2 -
 net/ipv6/ip6_output.c                    |    4 ++
 76 files changed, 464 insertions(+), 182 deletions(-)
author
#63 lore raw

PATCH 1/49 USB: usb-storage: quirk around v1.11 firmware on Nikon D4

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

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

From: Dave Jones <[email protected]>

commit b9a097f26e55968cbc52e30a4a2e73d32d7604ce upstream

usb-storage: quirk around v1.11 firmware on Nikon D40

https://bugzilla.redhat.com/show_bug.cgi?id=454028
Just as in earlier firmware versions, we need to perform this quirk for the latest version too.

Speculatively do the entry for the D80 too, as they seem to have the same firmware problems historically.

---
 drivers/usb/storage/unusual_devs.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/storage/unusual_devs.h +2 -2
@@ -357,14 +357,14 @@ UNUSUAL_DEV(  0x04b0, 0x040f, 0x0100, 0x
 		US_FL_FIX_CAPACITY),
 
 /* Reported by Emil Larsson <[email protected]> */
-UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0110,
+UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0111,
 		"NIKON",
 		"NIKON DSC D80",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_CAPACITY),
 
 /* Reported by Ortwin Glueck <[email protected]> */
-UNUSUAL_DEV(  0x04b0, 0x0413, 0x0110, 0x0110,
+UNUSUAL_DEV(  0x04b0, 0x0413, 0x0110, 0x0111,
 		"NIKON",
 		"NIKON DSC D40",
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
author
#64 lore raw

PATCH 2/49 usb-storage: unusual_devs entries for iRiver T10 and Datafab CF+SM reader

In reply to Greg KH

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

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

From: Alan Stern <[email protected]>

commit 368ee6469c327364ea10082a348f91c1f5ba47f7 upstream

This patch (as1115) adds unusual_devs entries with the IGNORE_RESIDE flag for the iRiver T10 and the Simple Tech/Datafab CF+SM card reader. Apparently these devices provide reasonable residue values for READ and WRITE operations, but not for others like INQUIRY or READ CAPACITY.

This fixes the iRiver T10 problem reported in Bugzilla #11125.

---
 drivers/usb/storage/unusual_devs.h |   14 ++++++++++++++
 1 file changed, 14 insertions(+)
drivers/usb/storage/unusual_devs.h +14 -0
@@ -1164,6 +1164,13 @@ UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
+/* Reported by Rauch Wolke <[email protected]> */
+UNUSUAL_DEV(  0x07c4, 0xa4a5, 0x0000, 0xffff,
+		"Simple Tech/Datafab",
+		"CF+SM Reader",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
  * to the USB storage specification in two ways:
  * - They tell us they are using transport protocol CBI. In reality they
@@ -1705,6 +1712,13 @@ UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x
 		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_GO_SLOW ),
 
+/* Reported by Andrey Rahmatullin <[email protected]> */
+UNUSUAL_DEV(  0x4102, 0x1020, 0x0100,  0x0100,
+		"iRiver",
+		"MP3 T10",
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_IGNORE_RESIDUE ),
+
 /*
  * David Härdeman <[email protected]>
  * The key makes the SCSI stack print confusing (but harmless) messages
author
#65 lore raw

PATCH 3/49 usb-serial: dont release unregistered minors

In reply to Greg KH

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

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

From: Alan Stern <[email protected]>

commit 0282b7f2a874e72c18fcd5a112ccf67f71ba7f5c upstream

This patch (as1121) fixes a bug in the USB serial core. When a device is unregistered, the core will give back its minors -- even if the device hasn't been assigned any!

The patch reserves the highest minor value (255) to mean that no minor was assigned. It also removes some dead code and does a small style fixup.

---
 drivers/usb/serial/usb-serial.c |    7 +++----
 include/linux/usb/serial.h      |    3 ++-
 2 files changed, 5 insertions(+), 5 deletions(-)
drivers/usb/serial/usb-serial.c +3 -4
@@ -119,9 +119,6 @@ static void return_serial(struct usb_ser
 
 	dbg("%s", __FUNCTION__);
 
-	if (serial == NULL)
-		return;
-
 	for (i = 0; i < serial->num_ports; ++i) {
 		serial_table[serial->minor + i] = NULL;
 	}
@@ -140,7 +137,8 @@ static void destroy_serial(struct kref *
 	serial->type->shutdown(serial);
 
 	/* return the minor range that this device had */
-	return_serial(serial);
+	if (serial->minor != SERIAL_TTY_NO_MINOR)
+		return_serial(serial);
 
 	for (i = 0; i < serial->num_ports; ++i)
 		serial->port[i]->open_count = 0;
@@ -635,6 +633,7 @@ static struct usb_serial * create_serial
 	serial->interface = interface;
 	kref_init(&serial->kref);
 	mutex_init(&serial->disc_mutex);
+	serial->minor = SERIAL_TTY_NO_MINOR;
 
 	return serial;
 }
include/linux/usb/serial.h +2 -1
@@ -18,7 +18,8 @@
 #include <linux/mutex.h>
 
 #define SERIAL_TTY_MAJOR	188	/* Nice legal number now */
-#define SERIAL_TTY_MINORS	255	/* loads of devices :) */
+#define SERIAL_TTY_MINORS	254	/* loads of devices :) */
+#define SERIAL_TTY_NO_MINOR	255	/* No minor was assigned */
 
 /* The maximum number of ports one device can grab at once */
 #define MAX_NUM_PORTS		8
author
#66 lore raw

PATCH 4/49 USB: pl2023: Remove USB id (4348:5523) handled by ch341

In reply to Greg KH

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

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

From: Tollef Fog Heen <[email protected]>

commit 8c809681ba0289afd0ed7bbb63679a0568dd441d upstream

USB ID 4348:5523 is handled by the ch341 driver. Remove it from the pl2023 driver.

Reverts 002e8f2c80c6be76bb312940bc278fc10b2b2487.

---
 drivers/usb/serial/pl2303.c |    1 -
 drivers/usb/serial/pl2303.h |    4 ----
 2 files changed, 5 deletions(-)
drivers/usb/serial/pl2303.c +0 -1
@@ -87,7 +87,6 @@ static struct usb_device_id id_table [] 
 	{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
 	{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
 	{ USB_DEVICE(COREGA_VENDOR_ID, COREGA_PRODUCT_ID) },
-	{ USB_DEVICE(HL340_VENDOR_ID, HL340_PRODUCT_ID) },
 	{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
drivers/usb/serial/pl2303.h +0 -4
@@ -105,10 +105,6 @@
 #define COREGA_VENDOR_ID	0x07aa
 #define COREGA_PRODUCT_ID	0x002a
 
-/* HL HL-340 (ID: 4348:5523) */
-#define HL340_VENDOR_ID		0x4348
-#define HL340_PRODUCT_ID	0x5523
-
 /* Y.C. Cable U.S.A., Inc - USB to RS-232 */
 #define YCCABLE_VENDOR_ID	0x05ad
 #define YCCABLE_PRODUCT_ID	0x0fba
author
#67 lore raw

PATCH 5/49 USB: ftdi_sio: Add USB Product Id for ELV HS485

In reply to Greg KH

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

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

From: Andre Schenk <[email protected]>

commit b5894a500127fce1db1309db5f9ca8b77a2ac266 upstream

USB product id registration for the ELV HS485 USB adapter (www.elv.de) to their home automation bus system. Applies to 2.6.26.

---
 drivers/usb/serial/ftdi_sio.c |    1 +
 drivers/usb/serial/ftdi_sio.h |    1 +
 2 files changed, 2 insertions(+)
drivers/usb/serial/ftdi_sio.c +1 -0
@@ -283,6 +283,7 @@ static struct usb_device_id id_table_com
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_FHZ1300PC_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_EM1010PC_PID) },
 	{ USB_DEVICE(FTDI_VID, FTDI_ELV_WS500_PID) },
+	{ USB_DEVICE(FTDI_VID, FTDI_ELV_HS485_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) },
 	{ USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) },
drivers/usb/serial/ftdi_sio.h +1 -0
@@ -256,6 +256,7 @@
 #define FTDI_ELV_WS300PC_PID	0xE0F6	/* PC-Wetterstation (WS 300 PC) */
 #define FTDI_ELV_FHZ1300PC_PID	0xE0E8	/* FHZ 1300 PC */
 #define FTDI_ELV_WS500_PID	0xE0E9	/* PC-Wetterstation (WS 500) */
+#define FTDI_ELV_HS485_PID	0xE0EA	/* USB to RS-485 adapter */
 #define FTDI_ELV_EM1010PC_PID	0xE0EF	/* Engery monitor EM 1010 PC */
 
 /*
author
#68 lore raw

PATCH 6/49 USB: ftdi_sio: add support for Luminance Stellaris Evaluation/Development Kits

In reply to Greg KH

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

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

From: Frederik Kriewitz <[email protected]>

commit a00c3cadc2bf50b3c925acdb3d0e5789b1650498 upstream

The Patch adds support for Luminance Stellaris Evaluation/Development Kits (FTDI 2232C based).
The PIDs were missing.

Successfully tested with a Stellaris LM3S8962 Evaluation kit.

---
 drivers/usb/serial/ftdi_sio.c |    4 ++++
 drivers/usb/serial/ftdi_sio.h |    5 +++++
 2 files changed, 9 insertions(+)
drivers/usb/serial/ftdi_sio.c +4 -0
@@ -367,6 +367,10 @@ static struct usb_device_id id_table_com
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(FTDI_VID, FTDI_OOCDLINK_PID),
 		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(FTDI_VID, LMI_LM3S_DEVEL_BOARD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+	{ USB_DEVICE(FTDI_VID, LMI_LM3S_EVAL_BOARD_PID),
+		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
 	{ USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) },
 	{ },					/* Optional parameter entry */
 	{ }					/* Terminating entry */
drivers/usb/serial/ftdi_sio.h +5 -0
@@ -548,6 +548,11 @@
 #define OLIMEX_VID			0x15BA
 #define OLIMEX_ARM_USB_OCD_PID		0x0003
 
+/* Luminary Micro Stellaris Boards, VID = FTDI_VID */
+/* FTDI 2332C Dual channel device, side A=245 FIFO (JTAG), Side B=RS232 UART */
+#define LMI_LM3S_DEVEL_BOARD_PID	0xbcd8
+#define LMI_LM3S_EVAL_BOARD_PID		0xbcd9
+
 /* www.elsterelectricity.com Elster Unicom III Optical Probe */
 #define FTDI_ELSTER_UNICOM_PID		0xE700 /* Product Id */
 
author
#69 lore raw

PATCH 7/49 SCSI: ses: fix VPD inquiry overrun

In reply to Greg KH

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

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

From: James Bottomley <[email protected]>

commit 671a99c8eb2f1dde08ac5538d8cd912047c61ddf upstream

There are a few kerneloops.org reports like this one:

http://www.kerneloops.org/search.php?search=ses_match_to_enclosure

That seem to imply we're running off the end of the VPD inquiry data (although at 512 bytes, it should be long enough for just about anything). we should be using correctly sized buffers anyway, so put those in and hope this oops goes away.

---
 drivers/scsi/ses.c |   18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
drivers/scsi/ses.c +14 -4
@@ -345,14 +345,14 @@ static int ses_enclosure_find_by_addr(st
 	return 0;
 }
 
-#define VPD_INQUIRY_SIZE 512
+#define VPD_INQUIRY_SIZE 36
 
 static void ses_match_to_enclosure(struct enclosure_device *edev,
 				   struct scsi_device *sdev)
 {
 	unsigned char *buf = kmalloc(VPD_INQUIRY_SIZE, GFP_KERNEL);
 	unsigned char *desc;
-	int len;
+	u16 vpd_len;
 	struct efd efd = {
 		.addr = 0,
 	};
@@ -372,9 +372,19 @@ static void ses_match_to_enclosure(struc
 			     VPD_INQUIRY_SIZE, NULL, SES_TIMEOUT, SES_RETRIES))
 		goto free;
 
-	len = (buf[2] << 8) + buf[3];
+	vpd_len = (buf[2] << 8) + buf[3];
+	kfree(buf);
+	buf = kmalloc(vpd_len, GFP_KERNEL);
+	if (!buf)
+		return;
+	cmd[3] = vpd_len >> 8;
+	cmd[4] = vpd_len & 0xff;
+	if (scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf,
+			     vpd_len, NULL, SES_TIMEOUT, SES_RETRIES))
+		goto free;
+
 	desc = buf + 4;
-	while (desc < buf + len) {
+	while (desc < buf + vpd_len) {
 		enum scsi_protocol proto = desc[0] >> 4;
 		u8 code_set = desc[0] & 0x0f;
 		u8 piv = desc[1] & 0x80;
author
#70 lore raw

PATCH 8/49 SCSI: scsi_transport_spi: fix oops in revalidate

In reply to Greg KH

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

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

From: James Bottomley <[email protected]>

commit e8bac9e0647dd04c83fd0bfe7cdfe2f6dfb100d0 upstream

The class_device->device conversion is causing an oops in revalidate because it's assuming that the device_for_each_child iterator will only return struct scsi_device children. The conversion made all former class_devices children of the device as well, so this assumption is broken. Fix it.

---
 drivers/scsi/scsi_transport_spi.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/scsi/scsi_transport_spi.c +5 -3
@@ -360,12 +360,14 @@ spi_transport_rd_attr(rti, "%d\n");
 spi_transport_rd_attr(pcomp_en, "%d\n");
 spi_transport_rd_attr(hold_mcs, "%d\n");
 
-/* we only care about the first child device so we return 1 */
+/* we only care about the first child device that's a real SCSI device
+ * so we return 1 to terminate the iteration when we find it */
 static int child_iter(struct device *dev, void *data)
 {
-	struct scsi_device *sdev = to_scsi_device(dev);
+	if (!scsi_is_sdev_device(dev))
+		return 0;
 
-	spi_dv_device(sdev);
+	spi_dv_device(to_scsi_device(dev));
 	return 1;
 }
 
author
#71 lore raw

PATCH 9/49 SCSI: hptiop: add more PCI device IDs

In reply to Greg KH

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

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

From: HighPoint Linux Team <[email protected]>

commit dd07428b44944b42f699408fe31af47977f1e733 upstream

Add PCI device ID for new adapter models.

---
 drivers/scsi/hptiop.c |    7 +++++++
 1 file changed, 7 insertions(+)
drivers/scsi/hptiop.c +7 -0
@@ -1246,6 +1246,13 @@ static struct pci_device_id hptiop_id_ta
 	{ PCI_VDEVICE(TTI, 0x3522), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3410), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3540), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x3530), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x3560), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4322), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4210), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4211), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4310), (kernel_ulong_t)&hptiop_itl_ops },
+	{ PCI_VDEVICE(TTI, 0x4311), (kernel_ulong_t)&hptiop_itl_ops },
 	{ PCI_VDEVICE(TTI, 0x3120), (kernel_ulong_t)&hptiop_mv_ops },
 	{ PCI_VDEVICE(TTI, 0x3122), (kernel_ulong_t)&hptiop_mv_ops },
 	{ PCI_VDEVICE(TTI, 0x3020), (kernel_ulong_t)&hptiop_mv_ops },
author
#72 lore raw

PATCH 10/49 SCSI: block: Fix miscalculation of sg_io timeout in CDROM_SEND_PACKET handler.

In reply to Greg KH

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

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

From: Tim Wright <[email protected]>

commit ad337591f4fd20de6a0ca03d6715267a5c1d2b16 upstream

It seems cdrwtool in the udftools has been unusable on "modern" kernels for some time. A Google search reveals many people with the same issue but no solution (cdrwtool fails to format the disk). After spending some time tracking down the issue, it comes down to the following:

The udftools still use the older CDROM_SEND_PACKET interface to send things like FORMAT_UNIT through to the drive. They should really be updated, but that's another story. Since most distros are using libata now, the cd or dvd burner appears as a SCSI device, and we wind up in block/scsi_ioctl.c. Here, the code tries to take the "struct cdrom_generic_command" and translate it and stuff it into a "struct sg_io_hdr" structure so it can pass it to the modern sg_io() routine instead. Unfortunately, there is one error, or rather an omission in the translation. The timeout that is passed in in the "struct cdrom_generic_command" is in HZ=100 units, and this is modified and correctly converted to jiffies by use of clock_t_to_jiffies(). However, a little further down, this cgc.timeout value in jiffies is simply copied into the sg_io_hdr timeout, which should be in milliseconds. Since most modern x86 kernels seems to be getting build with HZ=250, the timeout that is passed to sg_io and eventually converted to the timeout_per_command member of the scsi_cmnd structure is now four times too small. Since cdrwtool tries to set the timeout to one hour for the FORMAT_UNIT command, and it takes about 20 minutes to format a 4x CDRW, the SCSI error-handler kicks in after the FORMAT_UNIT completes because it took longer than the incorrectly-calculated timeout.

---
 block/scsi_ioctl.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
block/scsi_ioctl.c +1 -1
@@ -633,7 +633,7 @@ int scsi_cmd_ioctl(struct file *file, st
 			hdr.sbp = cgc.sense;
 			if (hdr.sbp)
 				hdr.mx_sb_len = sizeof(struct request_sense);
-			hdr.timeout = cgc.timeout;
+			hdr.timeout = jiffies_to_msecs(cgc.timeout);
 			hdr.cmdp = ((struct cdrom_generic_command __user*) arg)->cmd;
 			hdr.cmd_len = sizeof(cgc.cmd);
 
author
#73 lore raw

PATCH 11/49 relay: fix "full buffer with exactly full last subbuffer" accounting problem

In reply to Greg KH

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

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

From: Tom Zanussi <[email protected]>

commit 32194450330be327f3b25bf6b66298bd122599e9 upstream

In relay's current read implementation, if the buffer is completely full but hasn't triggered the buffer-full condition (i.e. the last write didn't cross the subbuffer boundary) and the last subbuffer is exactly full, the subbuffer accounting code erroneously finds nothing available. This patch fixes the problem.

Cc Eduard - Gabriel Munteanu <[email protected]>
Cc Pekka Enberg <[email protected]>
Cc Jens Axboe <[email protected]>
Cc Mathieu Desnoyers <[email protected]>
Cc Andrea Righi <[email protected]>
---
 kernel/relay.c |   12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)
kernel/relay.c +11 -1
@@ -803,6 +803,10 @@ static void relay_file_read_consume(stru
 	size_t n_subbufs = buf->chan->n_subbufs;
 	size_t read_subbuf;
 
+	if (buf->subbufs_produced == buf->subbufs_consumed &&
+	    buf->offset == buf->bytes_consumed)
+		return;
+
 	if (buf->bytes_consumed + bytes_consumed > subbuf_size) {
 		relay_subbufs_consumed(buf->chan, buf->cpu, 1);
 		buf->bytes_consumed = 0;
@@ -834,6 +838,8 @@ static int relay_file_read_avail(struct 
 
 	relay_file_read_consume(buf, read_pos, 0);
 
+	consumed = buf->subbufs_consumed;
+
 	if (unlikely(buf->offset > subbuf_size)) {
 		if (produced == consumed)
 			return 0;
@@ -852,8 +858,12 @@ static int relay_file_read_avail(struct 
 	if (consumed > produced)
 		produced += n_subbufs * subbuf_size;
 
-	if (consumed == produced)
+	if (consumed == produced) {
+		if (buf->offset == subbuf_size &&
+		    buf->subbufs_produced > buf->subbufs_consumed)
+			return 1;
 		return 0;
+	}
 
 	return 1;
 }
author
#74 lore raw

PATCH 12/49 radeonfb: fix accel engine hangs

In reply to Greg KH

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

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

From: David Miller <[email protected]>

commit 969830b2fedf8336c41d6195f49d250b1e166ff8 upstream

Some chips appear to have the 2D engine hang during screen redraw, typically in a sequence of copyarea operations. This appear to be solved by adding a flush of the engine destination pixel cache and waiting for the engine to be idle before issuing the accel operation. The performance impact seems to be fairly small.

Here is a trace on an RV370 (PCI device ID 0x5b64), it records the RBBM_STATUS register, then the source x/y, destination x/y, and width/height used for the copy:

----------------------------------------
radeonfb_prim_copyarea: STATUS[00000140] src[210:70] dst[210:60] wh[a0:10]
radeonfb_prim_copyarea: STATUS[00000140] src[2b8:70] dst[2b8:60] wh[88:10]
radeonfb_prim_copyarea: STATUS[00000140] src[348:70] dst[348:60] wh[40:10]
radeonfb_prim_copyarea: STATUS[80020140] src[390:70] dst[390:60] wh[88:10]
radeonfb_prim_copyarea: STATUS[8002613f] src[40:80] dst[40:70] wh[28:10]
radeonfb_prim_copyarea: STATUS[80026139] src[a8:80] dst[a8:70] wh[38:10]
radeonfb_prim_copyarea: STATUS[80026133] src[e8:80] dst[e8:70] wh[80:10]
radeonfb_prim_copyarea: STATUS[8002612d] src[170:80] dst[170:70] wh[30:10]
radeonfb_prim_copyarea: STATUS[80026127] src[1a8:80] dst[1a8:70] wh[8:10]
radeonfb_prim_copyarea: STATUS[80026121] src[1b8:80] dst[1b8:70] wh[88:10]
radeonfb_prim_copyarea: STATUS[8002611b] src[248:80] dst[248:70] wh[68:10]
----------------------------------------

When things are going fine the copies complete before the next ROP is even issued, but all of a sudden the 2D unit becomes active (bit 17 in RBBM_STATUS) and the FIFO retry (bit 13) and FIFO pipeline busy (bit
14) are set as well. The FIFO begins to backup until it becomes full.

What happens next is the radeon_fifo_wait() times out, and we access the chip illegally leading to a bus error which usually wedges the box. None of this makes it to the console screen, of course :-) radeon_fifo_wait() should be modified to reset the accelerator when this timeout happens instead of programming the chip anyways.

----------------------------------------
radeonfb: FIFO Timeout !
ERROR(0): Cheetah error trap taken afsr[0010080005000000] afar[000007f900800e40] TL1(0)
ERROR(0): TPC[595114] TNPC[595118] O7[459788] TSTATE[11009601]
ERROR(0): TPC<radeonfb_copyarea+0xfc/0x248>
ERROR(0): M_SYND(0), E_SYND(0), Privileged
ERROR(0): Highest priority error (0000080000000000) "Bus error response from system bus"
ERROR(0): D-cache idx[0] tag[0000000000000000] utag[0000000000000000] stag[0000000000000000] ERROR(0): D-cache data0[0000000000000000] data1[0000000000000000] data2[0000000000000000] data3[0000000000000000] ERROR(0): I-cache idx[0] tag[0000000000000000] utag[0000000000000000] stag[0000000000000000] u[0000000000000000] l[00\

ERROR(0): I-cache INSN0[0000000000000000] INSN1[0000000000000000] INSN2[0000000000000000] INSN3[0000000000000000] ERROR(0): I-cache INSN4[0000000000000000] INSN5[0000000000000000] INSN6[0000000000000000] INSN7[0000000000000000] ERROR(0): E-cache idx[800e40] tag[000000000e049f4c]
ERROR(0): E-cache data0[fffff8127d300180] data1[00000000004b5384] data2[0000000000000000] data3[0000000000000000] Ker:xnel panic - not syncing: Irrecoverable deferred error trap.
----------------------------------------

Another quirk is that these copyarea calls will not happen until the first drivers/char/vt.c:redraw_screen() occurs. This will only happen if you 1) VC switch or 2) run "consolechars" or 3) unblank the screen.

This seems to happen because until a redraw_screen() the screen scrolling method used by fbcon is not finalized yet. I've seen this with other fb drivers too.

So if all you do is boot straight into X you will never see this bug on the relevant chips.

---
 drivers/video/aty/radeon_accel.c |    8 ++++++++
 include/video/radeon.h           |    4 ++++
 2 files changed, 12 insertions(+)
drivers/video/aty/radeon_accel.c +8 -0
@@ -55,6 +55,10 @@ static void radeonfb_prim_fillrect(struc
 	OUTREG(DP_WRITE_MSK, 0xffffffff);
 	OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
 
+	radeon_fifo_wait(2);
+	OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+	OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+
 	radeon_fifo_wait(2);  
 	OUTREG(DST_Y_X, (region->dy << 16) | region->dx);
 	OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height);
@@ -116,6 +120,10 @@ static void radeonfb_prim_copyarea(struc
 	OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0)
 			| (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0));
 
+	radeon_fifo_wait(2);
+	OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL);
+	OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE));
+
 	radeon_fifo_wait(3);
 	OUTREG(SRC_Y_X, (sy << 16) | sx);
 	OUTREG(DST_Y_X, (dy << 16) | dx);
include/video/radeon.h +4 -0
@@ -741,6 +741,10 @@
 #define SOFT_RESET_RB           		   (1 <<  6)
 #define SOFT_RESET_HDP          		   (1 <<  7)
 
+/* WAIT_UNTIL bit constants */
+#define WAIT_DMA_GUI_IDLE			   (1 << 9)
+#define WAIT_2D_IDLECLEAN			   (1 << 16)
+
 /* SURFACE_CNTL bit consants */
 #define SURF_TRANSLATION_DIS			   (1 << 8)
 #define NONSURF_AP0_SWP_16BPP			   (1 << 20)
author
#75 lore raw

PATCH 13/49 posix-timers: fix posix_timer_event() vs dequeue_signal() race

In reply to Greg KH

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

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

From: Oleg Nesterov <[email protected]>

commit ba661292a2bc6ddd305a212b0526e5dc22195fe7 upstream

The bug was reported and analysed by Mark McLoughlin <[email protected]>, the patch is based on his and Roland's suggestions.

posix_timer_event() always rewrites the pre-allocated siginfo before sending the signal. Most of the written info is the same all the time, but memset(0) is very wrong. If ->sigq is queued we can race with collect_signal() which can fail to find this siginfo looking at .si_signo, or copy_siginfo() can copy the wrong .si_code/si_tid/etc.

In short, sys_timer_settime() can in fact stop the active timer, or the user can receive the siginfo with the wrong .si_xxx values.

Move "memset(->info, 0)" from posix_timer_event() to alloc_posix_timer(), change send_sigqueue() to set .si_overrun = 0 when ->sigq is not queued. It would be nice to move the whole sigq->info initialization from send to create path, but this is not easy to do without uglifying timer_create() further.

As Roland rightly pointed out, we need more cleanups/fixes here, see the "FIXME" comment in the patch. Hopefully this patch makes sense anyway, and it can mask the most bad implications.

---
 kernel/posix-timers.c |   17 +++++++++++++----
 kernel/signal.c       |    1 +
 2 files changed, 14 insertions(+), 4 deletions(-)
kernel/posix-timers.c +13 -4
@@ -297,14 +297,22 @@ void do_schedule_next_timer(struct sigin
 		unlock_timer(timr, flags);
 }
 
-int posix_timer_event(struct k_itimer *timr,int si_private)
+int posix_timer_event(struct k_itimer *timr, int si_private)
 {
-	memset(&timr->sigq->info, 0, sizeof(siginfo_t));
+	/*
+	 * FIXME: if ->sigq is queued we can race with
+	 * dequeue_signal()->do_schedule_next_timer().
+	 *
+	 * If dequeue_signal() sees the "right" value of
+	 * si_sys_private it calls do_schedule_next_timer().
+	 * We re-queue ->sigq and drop ->it_lock().
+	 * do_schedule_next_timer() locks the timer
+	 * and re-schedules it while ->sigq is pending.
+	 * Not really bad, but not that we want.
+	 */
 	timr->sigq->info.si_sys_private = si_private;
-	/* Send signal to the process that owns this timer.*/
 
 	timr->sigq->info.si_signo = timr->it_sigev_signo;
-	timr->sigq->info.si_errno = 0;
 	timr->sigq->info.si_code = SI_TIMER;
 	timr->sigq->info.si_tid = timr->it_id;
 	timr->sigq->info.si_value = timr->it_sigev_value;
@@ -438,6 +446,7 @@ static struct k_itimer * alloc_posix_tim
 		kmem_cache_free(posix_timers_cache, tmr);
 		tmr = NULL;
 	}
+	memset(&tmr->sigq->info, 0, sizeof(siginfo_t));
 	return tmr;
 }
 
kernel/signal.c +1 -0
@@ -1312,6 +1312,7 @@ int send_sigqueue(int sig, struct sigque
 		ret = -1;
 		goto out_err;
 	}
+	q->info.si_overrun = 0;
 
 	if (unlikely(!list_empty(&q->list))) {
 		/*
author
#76 lore raw

PATCH 14/49 posix-timers: do_schedule_next_timer: fix the setting of ->si_overrun

In reply to Greg KH

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

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

From: Oleg Nesterov <[email protected]>

commit 54da1174922cddd4be83d5a364b2e0fdd693f513 upstream

do_schedule_next_timer() sets info->si_overrun = timr->it_overrun_last, this discards the already accumulated overruns.

Cc Mark McLoughlin <[email protected]>
Cc Oliver Pinter <[email protected]>
Cc Roland McGrath <[email protected]>
Cc Andrew Morton <[email protected]>
---
 kernel/posix-timers.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/posix-timers.c +1 -1
@@ -290,7 +290,7 @@ void do_schedule_next_timer(struct sigin
 		else
 			schedule_next_timer(timr);
 
-		info->si_overrun = timr->it_overrun_last;
+		info->si_overrun += timr->it_overrun_last;
 	}
 
 	if (timr)
author
#77 lore raw

PATCH 15/49 mlock() fix return values

In reply to Greg KH

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

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

From: KOSAKI Motohiro <[email protected]>

commit a477097d9c37c1cf289c7f0257dffcfa42d50197 upstream

Halesh says:

Please find the below testcase provide to test mlock.

Test Case :
===========================

#include <sys/resource.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>

int main(void)
{
int fd,ret, i = 0;
char *addr, *addr1 = NULL;
unsigned int page_size;
struct rlimit rlim;

  if (0 != geteuid())
  {
   printf("Execute this pgm as root\n");
   exit(1);
  }

  /* create a file */
  if ((fd = open("mmap_test.c",O_RDWR|O_CREAT,0755)) == -1)
  {
   printf("cant create test file\n");
   exit(1);
  }

  page_size = sysconf(_SC_PAGE_SIZE);

  /* set the MEMLOCK limit */
  rlim.rlim_cur = 2000;
  rlim.rlim_max = 2000;

  if ((ret = setrlimit(RLIMIT_MEMLOCK,&rlim)) != 0)
  {
   printf("Cant change limit values\n");
   exit(1);
  }

addr = 0;
while (1)
{
/* map a page into memory each time*/
if ((addr = (char *) mmap(addr,page_size, PROT_READ |
PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED)
{
printf("cant do mmap on file\n");
exit(1);
}

if (0 == i)

    addr1 = addr;

i++;
errno = 0;
/* lock the mapped memory pagewise*/
if ((ret = mlock((char *)addr, 1500)) == -1)
{
printf("errno value is %d\n", errno);
printf("cant lock maped region\n");
exit(1);
}
addr = addr + page_size;
}
}
======================================================

This testcase results in an mlock() failure with errno 14 that is EFAULT, but it has nowhere been specified that mlock() will return EFAULT. When I tested the same on older kernels like 2.6.18, I got the correct result i.e errno 12 (ENOMEM).

I think in source code mlock(2), setting errno ENOMEM has been missed in do_mlock() , on mlock_fixup() failure.

SUSv3 requires the following behavior frmo mlock(2).

[ENOMEM]
Some or all of the address range specified by the addr and len arguments does not correspond to valid mapped pages in the address space of the process.

[EAGAIN]
Some or all of the memory identified by the operation could not be locked when the call was made.

This rule isn't so nice and slighly strange. but many people think POSIX/SUS compliance is important.

---
 mm/memory.c |   16 +++++++++++++---
 mm/mlock.c  |    2 --
 2 files changed, 13 insertions(+), 5 deletions(-)
mm/memory.c +13 -3
@@ -2618,16 +2618,26 @@ int make_pages_present(unsigned long add
 
 	vma = find_vma(current->mm, addr);
 	if (!vma)
-		return -1;
+		return -ENOMEM;
 	write = (vma->vm_flags & VM_WRITE) != 0;
 	BUG_ON(addr >= end);
 	BUG_ON(end > vma->vm_end);
 	len = DIV_ROUND_UP(end, PAGE_SIZE) - addr/PAGE_SIZE;
 	ret = get_user_pages(current, current->mm, addr,
 			len, write, 0, NULL, NULL);
-	if (ret < 0)
+	if (ret < 0) {
+		/*
+		   SUS require strange return value to mlock
+		    - invalid addr generate to ENOMEM.
+		    - out of memory should generate EAGAIN.
+		*/
+		if (ret == -EFAULT)
+			ret = -ENOMEM;
+		else if (ret == -ENOMEM)
+			ret = -EAGAIN;
 		return ret;
-	return ret == len ? 0 : -1;
+	}
+	return ret == len ? 0 : -ENOMEM;
 }
 
 #if !defined(__HAVE_ARCH_GATE_AREA)
mm/mlock.c +0 -2
@@ -78,8 +78,6 @@ success:
 
 	mm->locked_vm -= pages;
 out:
-	if (ret == -ENOMEM)
-		ret = -EAGAIN;
 	return ret;
 }
 
author
#78 lore raw

PATCH 16/49 matrox maven: fix a broken error path

In reply to Greg KH

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

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

From: Jean Delvare <[email protected]>

commit 5ede40f87957c6ededf9284c8339722a97b9dfb6 upstream

I broke an error path with d03c21ec0be7787ff6b75dcf56c0e96209ccbfbd, sorry about that.

The machine will crash if the i2c_attach_client() or maven_init_client() calls fail, although nobody has yet reported this happening.

---
 drivers/video/matrox/matroxfb_maven.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/video/matrox/matroxfb_maven.c +1 -1
@@ -1266,7 +1266,7 @@ static int maven_detect_client(struct i2
 ERROR4:;
 	i2c_detach_client(new_client);
 ERROR3:;
-	kfree(new_client);
+	kfree(data);
 ERROR0:;
 	return err;
 }
author
#79 lore raw

PATCH 17/49 ipvs: Fix possible deadlock in estimator code

In reply to Greg KH

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

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

From: Sven Wegener <[email protected]>

commit 8ab19ea36c5c5340ff598e4d15fc084eb65671dc upstream

There is a slight chance for a deadlock in the estimator code. We can't call del_timer_sync() while holding our lock, as the timer might be active and spinning for the lock on another cpu. Work around this issue by using try_to_del_timer_sync() and releasing the lock. We could actually delete the timer outside of our lock, as the add and kill functions are only every called from userspace via [gs]etsockopt() and are serialized by a mutex, but better make this explicit.

---
 net/ipv4/ipvs/ip_vs_est.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
net/ipv4/ipvs/ip_vs_est.c +5 -2
@@ -172,8 +172,11 @@ void ip_vs_kill_estimator(struct ip_vs_s
 		kfree(est);
 		killed++;
 	}
-	if (killed && est_list == NULL)
-		del_timer_sync(&est_timer);
+	while (killed && !est_list && try_to_del_timer_sync(&est_timer) < 0) {
+		write_unlock_bh(&est_lock);
+		cpu_relax();
+		write_lock_bh(&est_lock);
+	}
 	write_unlock_bh(&est_lock);
 }
 
#80 lore raw

Re: [patch 20/60] ipvs: Fix possible deadlock in estimator code

Quoted 29 lines · Greg KH

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

------------------
From: Sven Wegener <[email protected]>

commit 8ab19ea36c5c5340ff598e4d15fc084eb65671dc upstream

There is a slight chance for a deadlock in the estimator code. We can't call del_timer_sync() while holding our lock, as the timer might be active and spinning for the lock on another cpu. Work around this issue by using try_to_del_timer_sync() and releasing the lock. We could actually delete the timer outside of our lock, as the add and kill functions are only every called from userspace via [gs]etsockopt() and are serialized by a mutex, but better make this explicit.

---
 net/ipv4/ipvs/ip_vs_est.c |    7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)
net/ipv4/ipvs/ip_vs_est.c +0 -0
@@ -172,8 +172,11 @@ void ip_vs_kill_estimator(struct ip_vs_s
 		kfree(est);
 		killed++;
 	}

net/ipv4/ipvs/ip_vs_est.c void ip_vs_kill_estimator(struct ip_vs_s · line 182

Quoted 10 lines
net/ipv4/ipvs/ip_vs_est.c +5 -2
-	if (killed && est_list == NULL)
-		del_timer_sync(&est_timer);
+	while (killed && !est_list && try_to_del_timer_sync(&est_timer) < 0) {
+		write_unlock_bh(&est_lock);
+		cpu_relax();
+		write_lock_bh(&est_lock);
+	}
 	write_unlock_bh(&est_lock);
 }
 

Hi,

I am comfortable with this change for both 2.6.25-stable and 2.6.26-stable.

An arguably cleaner though more invasive fix, which will likely go into 2.6.28 is to use init and cleanup fuctions for the estimators as the empty case can actually only occur during the unload of IPVS.

See "ipvs: Create init functions for estimator code", which was posted by Sven to netdev & lvs-devel, and is currently living in horms/lvs-2.6.git on git.kernel.org.

author
#81 lore raw

PATCH 18/49 ide-cd: fix endianity for the error message in cdrom_read_capacity

In reply to Greg KH

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

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

From: Petr Tesarik <[email protected]>

commit 938bb03d188a1e688fb0bcae49788f540193e80a uptream

Aesthetic regards aside, commit e8e7b9eb11c34ee18bde8b7011af41938d1ad667 still leaves a bug in the error message, because it uses the unconverted big-endian value for printk.

Fix this by using a local variable in machine byte order. The result is correct, more readable, and also produces slightly shorter code on i386.

---
 drivers/ide/ide-cd.c |   18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)
drivers/ide/ide-cd.c +10 -8
@@ -1411,6 +1411,7 @@ static int cdrom_read_capacity(ide_drive
 
 	int stat;
 	struct request req;
+	u32 blocklen;
 
 	ide_cd_init_rq(drive, &req);
 
@@ -1427,23 +1428,24 @@ static int cdrom_read_capacity(ide_drive
 	/*
 	 * Sanity check the given block size
 	 */
-	switch (capbuf.blocklen) {
-	case __constant_cpu_to_be32(512):
-	case __constant_cpu_to_be32(1024):
-	case __constant_cpu_to_be32(2048):
-	case __constant_cpu_to_be32(4096):
+	blocklen = be32_to_cpu(capbuf.blocklen);
+	switch (blocklen) {
+	case 512:
+	case 1024:
+	case 2048:
+	case 4096:
 		break;
 	default:
 		printk(KERN_ERR "%s: weird block size %u\n",
-			drive->name, capbuf.blocklen);
+			drive->name, blocklen);
 		printk(KERN_ERR "%s: default to 2kb block size\n",
 			drive->name);
-		capbuf.blocklen = __constant_cpu_to_be32(2048);
+		blocklen = 2048;
 		break;
 	}
 
 	*capacity = 1 + be32_to_cpu(capbuf.lba);
-	*sectors_per_frame = be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
+	*sectors_per_frame = blocklen >> SECTOR_BITS;
 	return 0;
 }
 
author
#82 lore raw

PATCH 19/49 CIFS: mount of IPC$ breaks with iget patch

In reply to Greg KH

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

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

From: Steve French <[email protected]>

commit ad661334b8ae421154b121ee6ad3b56807adbf11 upstream

In looking at network named pipe support on cifs, I noticed that Dave Howell's iget patch:

iget: stop CIFS from using iget() and read_inode()

broke mounts to IPC$ (the interprocess communication share), and don't handle the error case (when getting info on the root inode fails).

Thanks to Gunter who noted a typo in a debug line in the original version of this patch.

---
 fs/cifs/inode.c |    1 +
 1 file changed, 1 insertion(+)
fs/cifs/inode.c +1 -0
@@ -639,6 +639,7 @@ struct inode *cifs_iget(struct super_blo
 		inode->i_fop = &simple_dir_operations;
 		inode->i_uid = cifs_sb->mnt_uid;
 		inode->i_gid = cifs_sb->mnt_gid;
+	} else if (rc) {
 		_FreeXid(xid);
 		iget_failed(inode);
 		return ERR_PTR(rc);
author
#83 lore raw

PATCH 20/49 CIFS: if get root inode fails during mount, cleanup tree connection

In reply to Greg KH

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

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

From: Steve French <[email protected]>

commit 2c731afb0d4ba16018b400c75665fbdb8feb2175 upstream

---
 fs/cifs/cifsfs.c |    2 ++
 1 file changed, 2 insertions(+)
fs/cifs/cifsfs.c +2 -0
@@ -175,6 +175,8 @@ out_no_root:
 	if (inode)
 		iput(inode);
 
+	cifs_umount(sb, cifs_sb);
+
 out_mount_failed:
 	if (cifs_sb) {
 #ifdef CONFIG_CIFS_DFS_UPCALL
author
#84 lore raw

PATCH 21/49 acer-wmi: Fix wireless and bluetooth on early AMW0 v2 laptops

In reply to Greg KH

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

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

From: Carlos Corbacho <[email protected]>

commit 5c742b45dd5fbbb6cf74d3378341704f4b23c5e8 upstream

In the old acer_acpi, I discovered that on some of the newer AMW0 laptops that supported the WMID methods, they don't work properly for setting the wireless and bluetooth values.

So for the AMW0 V2 laptops, we want to use both the 'old' AMW0 and the 'new' WMID methods for setting wireless & bluetooth to guarantee we always enable it.

This was fixed in acer_acpi some time ago, but I forgot to port the patch over to acer-wmi when it was merged.

(Without this patch, early AMW0 V2 laptops such as the Aspire 5040 won't work with acer-wmi, where-as they did with the old acer_acpi).

AK: fix compilation

---
 drivers/misc/acer-wmi.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
drivers/misc/acer-wmi.c +19 -0
@@ -742,11 +742,30 @@ static acpi_status get_u32(u32 *value, u
 
 static acpi_status set_u32(u32 value, u32 cap)
 {
+	acpi_status status;
+
 	if (interface->capability & cap) {
 		switch (interface->type) {
 		case ACER_AMW0:
 			return AMW0_set_u32(value, cap, interface);
 		case ACER_AMW0_V2:
+			if (cap == ACER_CAP_MAILLED)
+				return AMW0_set_u32(value, cap, interface);
+
+			/*
+			 * On some models, some WMID methods don't toggle
+			 * properly. For those cases, we want to run the AMW0
+			 * method afterwards to be certain we've really toggled
+			 * the device state.
+			 */
+			if (cap == ACER_CAP_WIRELESS ||
+				cap == ACER_CAP_BLUETOOTH) {
+				status = WMID_set_u32(value, cap, interface);
+				if (ACPI_FAILURE(status))
+					return status;
+
+				return AMW0_set_u32(value, cap, interface);
+			}
 		case ACER_WMID:
 			return WMID_set_u32(value, cap, interface);
 		default:
author
#85 lore raw

PATCH 22/49 dccp: change L/R must have at least one byte in the dccpsf_val field

In reply to Greg KH

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

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

From: Arnaldo Carvalho de Melo <[email protected]>

commit 3e8a0a559c66ee9e7468195691a56fefc3589740 upstream

Thanks to Eugene Teo for reporting this problem.

---
 net/dccp/proto.c |    5 +++++
 1 file changed, 5 insertions(+)
net/dccp/proto.c +5 -0
@@ -477,6 +477,11 @@ static int dccp_setsockopt_change(struct
 
 	if (copy_from_user(&opt, optval, sizeof(opt)))
 		return -EFAULT;
+	/*
+	 * rfc4340: 6.1. Change Options
+	 */
+	if (opt.dccpsf_len < 1)
+		return -EINVAL;
 
 	val = kmalloc(opt.dccpsf_len, GFP_KERNEL);
 	if (!val)
author
#86 lore raw

PATCH 23/49 random32: seeding improvement

In reply to Greg KH

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

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

From: Stephen Hemminger <[email protected]>

[ Upstream commit 697f8d0348a652593d195a13dd1067d9df911a82 ]

The rationale is:
* use u32 consistently
* no need to do LCG on values from (better) get_random_bytes
* use more data from get_random_bytes for secondary seeding
* don't reduce state space on srandom32()
* enforce state variable initialization restrictions

Note: the second paper has a version of random32() with even longer period and a version of random64() if needed.

---
 lib/random32.c |   48 +++++++++++++++++++++++++++---------------------
 1 file changed, 27 insertions(+), 21 deletions(-)
lib/random32.c +27 -21
@@ -56,23 +56,12 @@ static u32 __random32(struct rnd_state *
 	return (state->s1 ^ state->s2 ^ state->s3);
 }
 
-static void __set_random32(struct rnd_state *state, unsigned long s)
+/*
+ * Handle minimum values for seeds
+ */
+static inline u32 __seed(u32 x, u32 m)
 {
-	if (s == 0)
-		s = 1;      /* default seed is 1 */
-
-#define LCG(n) (69069 * n)
-	state->s1 = LCG(s);
-	state->s2 = LCG(state->s1);
-	state->s3 = LCG(state->s2);
-
-	/* "warm it up" */
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
-	__random32(state);
+	return (x < m) ? x + m : x;
 }
 
 /**
@@ -107,7 +96,7 @@ void srandom32(u32 entropy)
 	 */
 	for_each_possible_cpu (i) {
 		struct rnd_state *state = &per_cpu(net_rand_state, i);
-		__set_random32(state, state->s1 ^ entropy);
+		state->s1 = __seed(state->s1 ^ entropy, 1);
 	}
 }
 EXPORT_SYMBOL(srandom32);
@@ -122,7 +111,19 @@ static int __init random32_init(void)
 
 	for_each_possible_cpu(i) {
 		struct rnd_state *state = &per_cpu(net_rand_state,i);
-		__set_random32(state, i + jiffies);
+
+#define LCG(x)	((x) * 69069)	/* super-duper LCG */
+		state->s1 = __seed(LCG(i + jiffies), 1);
+		state->s2 = __seed(LCG(state->s1), 7);
+		state->s3 = __seed(LCG(state->s2), 15);
+
+		/* "warm it up" */
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
+		__random32(state);
 	}
 	return 0;
 }
@@ -135,13 +136,18 @@ core_initcall(random32_init);
 static int __init random32_reseed(void)
 {
 	int i;
-	unsigned long seed;
 
 	for_each_possible_cpu(i) {
 		struct rnd_state *state = &per_cpu(net_rand_state,i);
+		u32 seeds[3];
+
+		get_random_bytes(&seeds, sizeof(seeds));
+		state->s1 = __seed(seeds[0], 1);
+		state->s2 = __seed(seeds[1], 7);
+		state->s3 = __seed(seeds[2], 15);
 
-		get_random_bytes(&seed, sizeof(seed));
-		__set_random32(state, seed);
+		/* mix it in */
+		__random32(state);
 	}
 	return 0;
 }
author
#87 lore raw

PATCH 24/49 ipv6: Fix ip6_xmit to send fragments if ipfragok is true

In reply to Greg KH

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

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

From: Wei Yongjun <[email protected]>

[ Upstream commit 77e2f14f71d68d05945f1d30ca55b5194d6ab1ce ]

SCTP used ip6_xmit() to send fragments after received ICMP packet too big message. But while send packet used ip6_xmit, the skb->local_df is not initialized. So when skb if enter ip6_fragment(), the following code will discard the skb.

ip6_fragment(...)

{
    if (!skb->local_df) {
        ...
        return -EMSGSIZE;
    }
    ...
}

SCTP do the following step:
1. send packet ip6_xmit(skb, ipfragok=0)
2. received ICMP packet too big message
3. if PMTUD_ENABLE: ip6_xmit(skb, ipfragok=1)

This patch fixed the problem by set local_df if ipfragok is true.

---
 net/ipv6/ip6_output.c |    4 ++++
 1 file changed, 4 insertions(+)
net/ipv6/ip6_output.c +4 -0
@@ -229,6 +229,10 @@ int ip6_xmit(struct sock *sk, struct sk_
 	skb_reset_network_header(skb);
 	hdr = ipv6_hdr(skb);
 
+	/* Allow local fragmentation. */
+	if (ipfragok)
+		skb->local_df = 1;
+
 	/*
 	 *	Fill in the IPv6 header
 	 */
author
#88 lore raw

PATCH 25/49 sparc64: FUTEX_OP_ANDN fix

In reply to Greg KH

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

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

From: Mikael Pettersson <[email protected]>

[ Upstream commit d72609e17fd93bb2f7e0f7e1bdc70b6d20e43843 ]

Correct sparc64's implementation of FUTEX_OP_ANDN to do a bitwise negate of the oparg parameter before applying the AND operation. All other archs that support FUTEX_OP_ANDN either negate oparg explicitly (frv, ia64, mips, sh, x86), or do so indirectly by using an and-not instruction (powerpc). Since sparc64 has and-not, I chose to use that solution.

I've not found any use of FUTEX_OP_ANDN in glibc so the impact of this bug is probably minor. But other user-space components may try to use it so it should still get fixed.

---
 include/asm-sparc64/futex.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/asm-sparc64/futex.h +1 -1
@@ -59,7 +59,7 @@ static inline int futex_atomic_op_inuser
 		__futex_cas_op("or\t%2, %4, %1", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_ANDN:
-		__futex_cas_op("and\t%2, %4, %1", ret, oldval, uaddr, oparg);
+		__futex_cas_op("andn\t%2, %4, %1", ret, oldval, uaddr, oparg);
 		break;
 	case FUTEX_OP_XOR:
 		__futex_cas_op("xor\t%2, %4, %1", ret, oldval, uaddr, oparg);
author
#89 lore raw

PATCH 26/49 sparc64: Do not clobber %g7 in setcontext() trap.

In reply to Greg KH

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

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

From: David S. Miller <[email protected]>

[ Upstream commit 0a4949c4414af2eb91414bcd8e2a8ac3706f7dde ]

That's the userland thread register, so we should never try to change it like this.

Based upon glibc bug nptl/6577 and suggestions by Jakub Jelinek.

---
 arch/sparc64/kernel/signal.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
arch/sparc64/kernel/signal.c +4 -2
@@ -2,7 +2,7 @@
  *  arch/sparc64/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
- *  Copyright (C) 1995 David S. Miller ([email protected])
+ *  Copyright (C) 1995, 2008 David S. Miller ([email protected])
  *  Copyright (C) 1996 Miguel de Icaza ([email protected])
  *  Copyright (C) 1997 Eddie C. Dost   ([email protected])
  *  Copyright (C) 1997,1998 Jakub Jelinek   ([email protected])
@@ -90,7 +90,9 @@ asmlinkage void sparc64_set_context(stru
 	err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
 	err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
 	err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
-	err |= __get_user(regs->u_regs[UREG_G7], (&(*grp)[MC_G7]));
+
+	/* Skip %g7 as that's the thread register in userspace.  */
+
 	err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
 	err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
 	err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
author
#90 lore raw

PATCH 27/49 uml: fix build when SLOB is enabled

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 43f5b3085fdd27c4edf535d938b2cb0ccead4f75 upstream

Reintroduce uml_kmalloc for the benefit of UML libc code. The previous tactic of declaring __kmalloc so it could be called directly from the libc side of the house turned out to be getting too intimate with slab, and it doesn't work with slob.

So, the uml_kmalloc wrapper is back. It calls kmalloc or whatever that translates into, and libc code calls it.

kfree is left alone since that still works, leaving a somewhat inconsistent API.

---
 arch/um/drivers/chan_user.c              |    1 +
 arch/um/drivers/cow_sys.h                |    2 +-
 arch/um/drivers/daemon_user.c            |    4 ++--
 arch/um/drivers/fd.c                     |    2 +-
 arch/um/drivers/mcast_user.c             |    3 ++-
 arch/um/drivers/net_user.c               |    2 +-
 arch/um/drivers/port_user.c              |    2 +-
 arch/um/drivers/pty.c                    |    2 +-
 arch/um/drivers/slip_user.c              |    2 +-
 arch/um/drivers/tty.c                    |    2 +-
 arch/um/drivers/xterm.c                  |    2 +-
 arch/um/include/um_malloc.h              |    9 +++------
 arch/um/kernel/mem.c                     |    5 +++++
 arch/um/os-Linux/drivers/ethertap_user.c |    4 ++--
 arch/um/os-Linux/helper.c                |    4 ++--
 arch/um/os-Linux/main.c                  |    2 +-
 arch/um/os-Linux/sigio.c                 |    4 ++--
 17 files changed, 28 insertions(+), 24 deletions(-)
arch/um/drivers/chan_user.c +1 -0
@@ -11,6 +11,7 @@
 #include <termios.h>
 #include <sys/ioctl.h>
 #include "chan_user.h"
+#include "kern_constants.h"
 #include "os.h"
 #include "um_malloc.h"
 #include "user.h"
arch/um/drivers/cow_sys.h +1 -1
@@ -8,7 +8,7 @@
 
 static inline void *cow_malloc(int size)
 {
-	return kmalloc(size, UM_GFP_KERNEL);
+	return uml_kmalloc(size, UM_GFP_KERNEL);
 }
 
 static inline void cow_free(void *ptr)
arch/um/drivers/daemon_user.c +2 -2
@@ -34,7 +34,7 @@ static struct sockaddr_un *new_addr(void
 {
 	struct sockaddr_un *sun;
 
-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
 	if (sun == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
 		       "failed\n");
@@ -83,7 +83,7 @@ static int connect_to_switch(struct daem
 		goto out_close;
 	}
 
-	sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+	sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
 	if (sun == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
 		       "failed\n");
arch/um/drivers/fd.c +1 -1
@@ -40,7 +40,7 @@ static void *fd_init(char *str, int devi
 		return NULL;
 	}
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 
arch/um/drivers/mcast_user.c +2 -1
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <netinet/in.h>
+#include "kern_constants.h"
 #include "mcast.h"
 #include "net_user.h"
 #include "um_malloc.h"
@@ -24,7 +25,7 @@ static struct sockaddr_in *new_addr(char
 {
 	struct sockaddr_in *sin;
 
-	sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
 	if (sin == NULL) {
 		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
 		       "failed\n");
arch/um/drivers/net_user.c +1 -1
@@ -222,7 +222,7 @@ static void change(char *dev, char *what
 		netmask[2], netmask[3]);
 
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	if (output == NULL)
 		printk(UM_KERN_ERR "change : failed to allocate output "
 		       "buffer\n");
arch/um/drivers/port_user.c +1 -1
@@ -47,7 +47,7 @@ static void *port_init(char *str, int de
 	if (kern_data == NULL)
 		return NULL;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		goto err;
 
arch/um/drivers/pty.c +1 -1
@@ -29,7 +29,7 @@ static void *pty_chan_init(char *str, in
 {
 	struct pty_chan *data;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 
arch/um/drivers/slip_user.c +1 -1
@@ -96,7 +96,7 @@ static int slip_tramp(char **argv, int f
 	pid = err;
 
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	if (output == NULL) {
 		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
 		       "buffer\n");
arch/um/drivers/tty.c +1 -1
@@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, in
 	}
 	str++;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 	*data = ((struct tty_chan) { .dev 	= str,
arch/um/drivers/xterm.c +1 -1
@@ -30,7 +30,7 @@ static void *xterm_init(char *str, int d
 {
 	struct xterm_chan *data;
 
-	data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
 	if (data == NULL)
 		return NULL;
 	*data = ((struct xterm_chan) { .pid 		= -1,
arch/um/include/um_malloc.h +3 -6
@@ -8,15 +8,12 @@
 
 #include "kern_constants.h"
 
-extern void *__kmalloc(int size, int flags);
-static inline void *kmalloc(int size, int flags)
-{
-	return __kmalloc(size, flags);
-}
-
+extern void *uml_kmalloc(int size, int flags);
 extern void kfree(const void *ptr);
 
 extern void *vmalloc(unsigned long size);
 extern void vfree(void *ptr);
 
 #endif /* __UM_MALLOC_H__ */
+
+
arch/um/kernel/mem.c +5 -0
@@ -375,3 +375,8 @@ pmd_t *pmd_alloc_one(struct mm_struct *m
 	return pmd;
 }
 #endif
+
+void *uml_kmalloc(int size, int flags)
+{
+	return kmalloc(size, flags);
+}
arch/um/os-Linux/drivers/ethertap_user.c +2 -2
@@ -52,7 +52,7 @@ static void etap_change(int op, unsigned
 		return;
 	}
 
-	output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+	output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
 	if (output == NULL)
 		printk(UM_KERN_ERR "etap_change : Failed to allocate output "
 		       "buffer\n");
@@ -165,7 +165,7 @@ static int etap_open(void *data)
 	err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
 			 control_fds[1], data_fds[0], data_fds[1]);
 	output_len = UM_KERN_PAGE_SIZE;
-	output = kmalloc(output_len, UM_GFP_KERNEL);
+	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
 	read_output(control_fds[0], output, output_len);
 
 	if (output == NULL)
arch/um/os-Linux/helper.c +2 -2
@@ -70,8 +70,8 @@ int run_helper(void (*pre_exec)(void *),
 	data.pre_data = pre_data;
 	data.argv = argv;
 	data.fd = fds[1];
-	data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
-					kmalloc(PATH_MAX, UM_GFP_KERNEL);
+	data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+					uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
 	pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
 	if (pid < 0) {
 		ret = -errno;
arch/um/os-Linux/main.c +1 -1
@@ -199,7 +199,7 @@ void *__wrap_malloc(int size)
 		return __real_malloc(size);
 	else if (size <= UM_KERN_PAGE_SIZE)
 		/* finding contiguous pages can be hard*/
-		ret = kmalloc(size, UM_GFP_KERNEL);
+		ret = uml_kmalloc(size, UM_GFP_KERNEL);
 	else ret = vmalloc(size);
 
 	/*
arch/um/os-Linux/sigio.c +2 -2
@@ -109,7 +109,7 @@ static int need_poll(struct pollfds *pol
 	if (n <= polls->size)
 		return 0;
 
-	new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
+	new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
 	if (new == NULL) {
 		printk(UM_KERN_ERR "need_poll : failed to allocate new "
 		       "pollfds\n");
@@ -243,7 +243,7 @@ static struct pollfd *setup_initial_poll
 {
 	struct pollfd *p;
 
-	p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
+	p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
 	if (p == NULL) {
 		printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
 		       "poll\n");
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#91 lore raw

PATCH 28/49 uml: fix bad NTP interaction with clock

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit cfd28f6695d0fc047478480791a21bdd4967f98e upstream

UML's supposed nanosecond clock interacts badly with NTP when NTP decides that the clock has drifted ahead and needs to be slowed down. Slowing down the clock is done by decrementing the cycle-to-nanosecond multiplier, which is 1. Decrementing that gives you 0 and time is stopped.

This is fixed by switching to a microsecond clock, with a multiplier of 1000.

---
 arch/um/kernel/time.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
arch/um/kernel/time.c +2 -2
@@ -74,7 +74,7 @@ static irqreturn_t um_timer(int irq, voi
 
 static cycle_t itimer_read(void)
 {
-	return os_nsecs();
+	return os_nsecs() / 1000;
 }
 
 static struct clocksource itimer_clocksource = {
@@ -82,7 +82,7 @@ static struct clocksource itimer_clockso
 	.rating		= 300,
 	.read		= itimer_read,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.mult		= 1,
+	.mult		= 1000,
 	.shift		= 0,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#92 lore raw

PATCH 29/49 uml: physical memory shouldnt include initial stack

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 60a2988aea701a6424809a5432bf068667aac177 upstream

The top of physical memory should be below the initial process stack, not the top of the address space, at least for as long as the stack isn't known to the kernel VM system and appropriately reserved.

---
 arch/um/kernel/um_arch.c |    5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/um/kernel/um_arch.c +4 -1
@@ -259,6 +259,7 @@ int __init linux_main(int argc, char **a
 	unsigned long avail, diff;
 	unsigned long virtmem_size, max_physmem;
 	unsigned int i, add;
+	unsigned long stack;
 	char * mode;
 
 	for (i = 1; i < argc; i++) {
@@ -347,7 +348,9 @@ int __init linux_main(int argc, char **a
 	}
 
 	virtmem_size = physmem_size;
-	avail = TASK_SIZE - start_vm;
+	stack = (unsigned long) argv;
+	stack &= ~(1024 * 1024 - 1);
+	avail = stack - start_vm;
 	if (physmem_size > avail)
 		virtmem_size = avail;
 	end_vm = start_vm + virtmem_size;
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#93 lore raw

PATCH 30/49 uml: track and make up lost ticks

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit fe2cc53ee013a4d4d0317d418e7019fe6533a5a8 upstream

Alarm delivery could be noticably late in the !CONFIG_NOHZ case because lost ticks weren't being taken into account. This is now treated more carefully, with the time between ticks being calculated and the appropriate number of ticks delivered to the timekeeping system.

---
 arch/um/include/process.h |    4 +--
 arch/um/os-Linux/signal.c |    1 
 arch/um/os-Linux/time.c   |   54 ++++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 53 insertions(+), 6 deletions(-)
arch/um/include/process.h +2 -2
@@ -8,8 +8,8 @@
 
 #include <signal.h>
 
-extern void sig_handler(int sig, struct sigcontext sc);
-extern void alarm_handler(int sig, struct sigcontext sc);
+extern void sig_handler(int sig, struct sigcontext *sc);
+extern void alarm_handler(int sig, struct sigcontext *sc);
 
 #endif
 
arch/um/os-Linux/signal.c +1 -0
@@ -12,6 +12,7 @@
 #include "as-layout.h"
 #include "kern_util.h"
 #include "os.h"
+#include "process.h"
 #include "sysdep/barrier.h"
 #include "sysdep/sigcontext.h"
 #include "user.h"
arch/um/os-Linux/time.c +50 -4

100 lines not on this page · raw message

Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#94 lore raw

PATCH 31/49 uml: missed kmalloc() in pcap_user.c

In reply to Greg KH

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

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

From: Al Viro <[email protected]>

commit 296cd66f7f6e130fe08e6880ecb13c3fc615a8db upstream

---
 arch/um/drivers/pcap_user.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/drivers/pcap_user.c +1 -1
@@ -50,7 +50,7 @@ static int pcap_open(void *data)
 			return -EIO;
 		}
 
-		pri->compiled = kmalloc(sizeof(struct bpf_program),
+		pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
 					UM_GFP_KERNEL);
 		if (pri->compiled == NULL) {
 			printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#95 lore raw

PATCH 32/49 uml: deal with host time going backwards

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 06e1e4ffbd1932e288839b3140cda6b8141eb684 upstream

Protection against the host's time going backwards (eg, ntp activity on the host) by keeping track of the time at the last tick and if it's greater than the current time, keep time stopped until the host catches up.

---
 arch/um/os-Linux/time.c |    7 +++++++
 1 file changed, 7 insertions(+)
arch/um/os-Linux/time.c +7 -0
@@ -106,6 +106,10 @@ static void deliver_alarm(void)
 	unsigned long long this_tick = os_nsecs();
 	int one_tick = UM_NSEC_PER_SEC / UM_HZ;
 
+	/* Protection against the host's time going backwards */
+	if ((last_tick != 0) && (this_tick < last_tick))
+		this_tick = last_tick;
+
 	if (last_tick == 0)
 		last_tick = this_tick - one_tick;
 
@@ -148,6 +152,9 @@ static int after_sleep_interval(struct t
 		start_usecs = usec;
 
 	start_usecs -= skew / UM_NSEC_PER_USEC;
+	if (start_usecs < 0)
+		start_usecs = 0;
+
 	tv = ((struct timeval) { .tv_sec  = start_usecs / UM_USEC_PER_SEC,
 				 .tv_usec = start_usecs % UM_USEC_PER_SEC });
 	interval = ((struct itimerval) { { 0, usec }, tv });
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#96 lore raw

PATCH 33/49 uml: deal with inaccessible address space start

In reply to Greg KH

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

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

From: Tom Spink <[email protected]>

commit 40fb16a360d9c6459afee91dc793c1e3374feb94 upstream

This patch makes os_get_task_size locate the bottom of the address space, as well as the top. This is for systems which put a lower limit on mmap addresses. It works by manually scanning pages from zero onwards until a valid page is found.

Because the bottom of the address space may not be zero, it's not sufficient to assume the top of the address space is the size of the address space. The size is the difference between the top address and bottom address.

[[email protected]: changed the name to reflect that this function is supposed to return the top of the process address space, not its size and changed the return value to reflect that. Also some minor formatting changes]

---
 arch/um/include/os.h                    |    2 -
 arch/um/kernel/um_arch.c                |    2 -
 arch/um/os-Linux/sys-i386/task_size.c   |   38 ++++++++++++++++++++++++--------
 arch/um/os-Linux/sys-x86_64/task_size.c |    2 -
 4 files changed, 32 insertions(+), 12 deletions(-)
arch/um/include/os.h +1 -1
@@ -298,6 +298,6 @@ extern int os_arch_prctl(int pid, int co
 extern int get_pty(void);
 
 /* sys-$ARCH/task_size.c */
-extern unsigned long os_get_task_size(void);
+extern unsigned long os_get_top_address(void);
 
 #endif
arch/um/kernel/um_arch.c +1 -1
@@ -273,7 +273,7 @@ int __init linux_main(int argc, char **a
 	if (have_root == 0)
 		add_arg(DEFAULT_COMMAND_LINE);
 
-	host_task_size = os_get_task_size();
+	host_task_size = os_get_top_address();
 	/*
 	 * TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
 	 * out
arch/um/os-Linux/sys-i386/task_size.c +29 -9
@@ -63,7 +63,7 @@ static int page_ok(unsigned long page)
 	return ok;
 }
 
-unsigned long os_get_task_size(void)
+unsigned long os_get_top_address(void)
 {
 	struct sigaction sa, old;
 	unsigned long bottom = 0;
@@ -76,9 +76,9 @@ unsigned long os_get_task_size(void)
 	 * hosts, but shouldn't hurt otherwise.
 	 */
 	unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
-	unsigned long test;
+	unsigned long test, original;
 
-	printf("Locating the top of the address space ... ");
+	printf("Locating the bottom of the address space ... ");
 	fflush(stdout);
 
 	/*
@@ -88,14 +88,32 @@ unsigned long os_get_task_size(void)
 	sa.sa_handler = segfault;
 	sigemptyset(&sa.sa_mask);
 	sa.sa_flags = SA_NODEFER;
-	sigaction(SIGSEGV, &sa, &old);
+	if (sigaction(SIGSEGV, &sa, &old)) {
+		perror("os_get_top_address");
+		exit(1);
+	}
 
-	if (!page_ok(bottom)) {
-		fprintf(stderr, "Address 0x%x no good?\n",
-			bottom << UM_KERN_PAGE_SHIFT);
+	/* Manually scan the address space, bottom-up, until we find
+	 * the first valid page (or run out of them).
+	 */
+	for (bottom = 0; bottom < top; bottom++) {
+		if (page_ok(bottom))
+			break;
+	}
+
+	/* If we've got this far, we ran out of pages. */
+	if (bottom == top) {
+		fprintf(stderr, "Unable to determine bottom of address "
+			"space.\n");
 		exit(1);
 	}
 
+	printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+	printf("Locating the top of the address space ... ");
+	fflush(stdout);
+
+	original = bottom;
+
 	/* This could happen with a 4G/4G split */
 	if (page_ok(top))
 		goto out;
@@ -110,8 +128,10 @@ unsigned long os_get_task_size(void)
 
 out:
 	/* Restore the old SIGSEGV handling */
-	sigaction(SIGSEGV, &old, NULL);
-
+	if (sigaction(SIGSEGV, &old, NULL)) {
+		perror("os_get_top_address");
+		exit(1);
+	}
 	top <<= UM_KERN_PAGE_SHIFT;
 	printf("0x%x\n", top);
 	fflush(stdout);
arch/um/os-Linux/sys-x86_64/task_size.c +1 -1
@@ -1,4 +1,4 @@
-unsigned long os_get_task_size(unsigned long shift)
+unsigned long os_get_top_address(unsigned long shift)
 {
 	/* The old value of CONFIG_TOP_ADDR */
 	return 0x7fc0000000;
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#97 lore raw

PATCH 34/49 uml: missing export of csum_partial() on uml/amd64

In reply to Greg KH

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

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

From: Al Viro <[email protected]>

commit 3e3b48e5198544dd90e27265a70c1a834139e025 upstream

---
 arch/um/sys-x86_64/ksyms.c |    1 +
 1 file changed, 1 insertion(+)
arch/um/sys-x86_64/ksyms.c +1 -0
@@ -14,3 +14,4 @@ EXPORT_SYMBOL(__up_wakeup);
 
 /*XXX: we need them because they would be exported by x86_64 */
 EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(csum_partial);
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#98 lore raw

PATCH 35/49 uml: memcpy export needs to follow host declaration

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 8bfd04b974689f700bbd053ad6e66b0a95fb80c9 upstream

x86_64 defines either memcpy or __memcpy depending on the gcc version, and it looks like UML needs to follow that in its exporting.

---
 arch/um/sys-x86_64/ksyms.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/um/sys-x86_64/ksyms.c +4 -0
@@ -13,5 +13,9 @@ EXPORT_SYMBOL(__down_failed_trylock);
 EXPORT_SYMBOL(__up_wakeup);
 
 /*XXX: we need them because they would be exported by x86_64 */
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
+EXPORT_SYMBOL(memcpy);
+#else
 EXPORT_SYMBOL(__memcpy);
+#endif
 EXPORT_SYMBOL(csum_partial);
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#99 lore raw

PATCH 36/49 uml: stub needs to tolerate SIGWINCH

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 3d5ede6f776bdb1483bcd086f79c3bf41fed3865 upstream

We lost the marking of SIGWINCH as being OK to receive during stub execution, causing a panic should that happen.

---
 arch/um/os-Linux/skas/process.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/um/os-Linux/skas/process.c +1 -1
@@ -55,7 +55,7 @@ static int ptrace_dump_regs(int pid)
  * Signals that are OK to receive in the stub - we'll just continue it.
  * SIGWINCH will happen when UML is inside a detached screen.
  */
-#define STUB_SIG_MASK (1 << SIGVTALRM)
+#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
 
 /* Signals that the stub will finish with - anything else is an error */
 #define STUB_DONE_MASK (1 << SIGTRAP)
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#100 lore raw

PATCH 37/49 uml: work around broken host PTRACE_SYSEMU

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit f1ef9167ca4494a8c6d71d0031c73e9c8841eadd upstream

Fedora broke PTRACE_SYSEMU again, and UML crashes as a result when it doesn't need to. This patch makes the PTRACE_SYSEMU check fail gracefully and makes UML fall back to PTRACE_SYSCALL.

---
 arch/um/os-Linux/start_up.c |   25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)
arch/um/os-Linux/start_up.c +16 -9
@@ -122,8 +122,10 @@ static int stop_ptraced_child(int pid, i
 {
 	int status, n, ret = 0;
 
-	if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
-		fatal_perror("stop_ptraced_child : ptrace failed");
+	if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
+		perror("stop_ptraced_child : ptrace failed");
+		return -1;
+	}
 	CATCH_EINTR(n = waitpid(pid, &status, 0));
 	if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
 		int exit_with = WEXITSTATUS(status);
@@ -203,7 +205,7 @@ static void __init check_sysemu(void)
 	if (n < 0)
 		fatal_perror("check_sysemu : wait failed");
 	if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
-		fatal("check_sysemu : expected SIGTRAP, got status = %d",
+		fatal("check_sysemu : expected SIGTRAP, got status = %d\n",
 		      status);
 
 	if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
@@ -245,9 +247,11 @@ static void __init check_sysemu(void)
 
 		if (WIFSTOPPED(status) &&
 		    (WSTOPSIG(status) == (SIGTRAP|0x80))) {
-			if (!count)
-				fatal("check_ptrace : SYSEMU_SINGLESTEP "
-				      "doesn't singlestep");
+			if (!count) {
+				non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
+					  "doesn't singlestep");
+				goto fail;
+			}
 			n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
 				   os_getpid());
 			if (n < 0)
@@ -257,9 +261,12 @@ static void __init check_sysemu(void)
 		}
 		else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
 			count++;
-		else
-			fatal("check_ptrace : expected SIGTRAP or "
-			      "(SIGTRAP | 0x80), got status = %d", status);
+		else {
+			non_fatal("check_ptrace : expected SIGTRAP or "
+				  "(SIGTRAP | 0x80), got status = %d\n",
+				  status);
+			goto fail;
+		}
 	}
 	if (stop_ptraced_child(pid, 0, 0) < 0)
 		goto fail_stopped;
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#101 lore raw

PATCH 38/49 uml: fix gcc ICEs and unresolved externs

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 4f81c5350b44bcc501ab6f8a089b16d064b4d2f6 upstream

There are various constraints on the use of unit-at-a-time:
- i386 uses no-unit-at-a-time for pre-4.0 (not 4.3)
- x86_64 uses unit-at-a-time always

Uli reported a crash on x86_64 with gcc 4.1.2 with unit-at-a-time, resulting in commit c0a18111e571138747a98af18b3a2124df56a0d1

Ingo reported a gcc internal error with gcc 4.3 with no-unit-at-a-timem, resulting in 22eecde2f9034764a3fd095eecfa3adfb8ec9a98

Benny Halevy is seeing extern inlines not resolved with gcc 4.3 with no-unit-at-a-time

This patch reintroduces unit-at-a-time for gcc >= 4.0, bringing back the possibility of Uli's crash. If that happens, we'll debug it.

I started seeing both the internal compiler errors and unresolved inlines on Fedora 9. This patch fixes both problems, without so far reintroducing the crash reported by Uli.

---
 arch/um/Makefile        |    1 -
 arch/um/Makefile-i386   |    7 +++++++
 arch/um/Makefile-x86_64 |    3 +++
 3 files changed, 10 insertions(+), 1 deletion(-)
arch/um/Makefile +0 -1
@@ -77,7 +77,6 @@ include $(srctree)/$(ARCH_DIR)/Makefile-
 KERNEL_DEFINES = $(strip -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
 			 -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES))
 KBUILD_CFLAGS += $(KERNEL_DEFINES)
-KBUILD_CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
 
 PHONY += linux
 
arch/um/Makefile-i386 +7 -0
@@ -32,4 +32,11 @@ cflags-y += $(call cc-option,-mpreferred
 # an unresolved reference.
 cflags-y += -ffreestanding
 
+# Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use
+# a lot more stack due to the lack of sharing of stacklots.  Also, gcc
+# 4.3.0 needs -funit-at-a-time for extern inline functions.
+KBUILD_CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then \
+			echo $(call cc-option,-fno-unit-at-a-time); \
+			else echo $(call cc-option,-funit-at-a-time); fi ;)
+
 KBUILD_CFLAGS += $(cflags-y)
arch/um/Makefile-x86_64 +3 -0
@@ -21,3 +21,6 @@ HEADER_ARCH := x86
 
 LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib64
 LINK-y += -m64
+
+# Do unit-at-a-time unconditionally on x86_64, following the host
+KBUILD_CFLAGS += $(call cc-option,-funit-at-a-time)
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#102 lore raw

PATCH 39/49 uml: Fix boot crash

In reply to Greg KH

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

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

From: Jeff Dike <[email protected]>

commit 7c1fed03b9fa32d4323d5caa6a9c7dcdd7eba767 upstream

My copying of linux/init.h didn't go far enough. The definition of __used singled out gcc minor version 3, but didn't care what the major version was. This broke when unit-at-a-time was added and gcc started throwing out initcalls.

This results in an early boot crash when ptrace tries to initialize a process with an empty, uninitialized register set.

---
 arch/um/include/init.h |    8 ++++++++
 1 file changed, 8 insertions(+)
arch/um/include/init.h +8 -0
@@ -45,6 +45,8 @@ typedef void (*exitcall_t)(void);
 # define __section(S) __attribute__ ((__section__(#S)))
 #endif
 
+#if __GNUC__ == 3
+
 #if __GNUC_MINOR__ >= 3
 # define __used			__attribute__((__used__))
 #else
@@ -52,6 +54,12 @@ typedef void (*exitcall_t)(void);
 #endif
 
 #else
+#if __GNUC__ == 4
+# define __used			__attribute__((__used__))
+#endif
+#endif
+
+#else
 #include <linux/compiler.h>
 #endif
 /* These are for everybody (although not all archs will actually
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#103 lore raw

PATCH 40/49 uml: PATH_MAX needs limits.h

In reply to Greg KH

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

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

From: Ingo Molnar <[email protected]>

commit b6d8adf477439e7086224bc9674c6b6638780783 upstream.

Include limits.h to get a definition of PATH_MAX.

---
 arch/um/os-Linux/helper.c |    1 +
 1 file changed, 1 insertion(+)
arch/um/os-Linux/helper.c +1 -0
@@ -7,6 +7,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <sched.h>
+#include <linux/limits.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
 #include "kern_constants.h"
Signature · 9 lines
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
User-mode-linux-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/user-mode-linux-devel
author
#104 lore raw

PATCH 41/49 radeon: misc corrections

In reply to Greg KH

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

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

From: David Miller <[email protected]>

Commit efc491814308f89d5ef6c4fe19ae4552a67d4132 upstream

radeon: misc corrections

I have a new PCI-E radeon RV380 series card (PCI device ID 5b64) that hangs in my sparc64 boxes when the init scripts set the font. The problem goes away if I disable acceleration.

I haven't figured out that bug yet, but along the way I found some corrections to make based upon some auditing.

1) The RB2D_DC_FLUSH_ALL value used by the kernel fb driver and the XORG video driver differ. I've made the kernel match what XORG is using.

2) In radeonfb_engine_reset() we have top-level code structure that roughly looks like:

	if (family is 300, 350, or V350)
		do this;
	else
		do that;
	...
	if (family is NOT 300, OR
	    family is NOT 350, OR
	    family is NOT V350)
		do another thing;

this last conditional makes no sense, is always true, and obviously was likely meant to be "family is NOT 300, 350, or V350". So I've made the code match the intent.

---
 drivers/video/aty/radeon_accel.c |    4 ++--
 include/video/radeon.h           |    5 +++--
 2 files changed, 5 insertions(+), 4 deletions(-)
drivers/video/aty/radeon_accel.c +2 -2
@@ -249,8 +249,8 @@ void radeonfb_engine_reset(struct radeon
 	INREG(HOST_PATH_CNTL);
 	OUTREG(HOST_PATH_CNTL, host_path_cntl);
 
-	if (rinfo->family != CHIP_FAMILY_R300 ||
-	    rinfo->family != CHIP_FAMILY_R350 ||
+	if (rinfo->family != CHIP_FAMILY_R300 &&
+	    rinfo->family != CHIP_FAMILY_R350 &&
 	    rinfo->family != CHIP_FAMILY_RV350)
 		OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset);
 
include/video/radeon.h +3 -2
@@ -527,8 +527,9 @@
 
 
 /* DSTCACHE_CTLSTAT bit constants */
-#define RB2D_DC_FLUSH				   (3 << 0)
-#define RB2D_DC_FLUSH_ALL			   0xf
+#define RB2D_DC_FLUSH_2D			   (1 << 0)
+#define RB2D_DC_FREE_2D				   (1 << 2)
+#define RB2D_DC_FLUSH_ALL			   (RB2D_DC_FLUSH_2D | RB2D_DC_FREE_2D)
 #define RB2D_DC_BUSY				   (1 << 31)
 
 
author
#105 lore raw

PATCH 42/49 r8169: avoid thrashing PCI conf space above RTL_GIGA_MAC_VER_06

In reply to Greg KH

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

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

From: Marcus Sundberg <[email protected]>

commit 77332894c21165404496c56763d7df6c15c4bb09 upstream

The magic write to register 0x82 will often cause PCI config space on my 8168 (PCI ID 10ec:8168, revision 2. mounted in an LG P300 laptop) to be filled with ones during driver load, and thus breaking NIC operation until reboot. If it does not happen on first driver load it can easily be reproduced by unloading and loading the driver a few times.

The magic write was added long ago by this commit:

Author: François Romieu <[email protected]>
Date:   Sat Jan 10 06:00:46 2004 -0500

[netdrvr r8169] Merge of changes done by Realtek to rtl8169_init_one():
- phy capability settings allows lower or equal capability as suggested in Realtek's changes;
- I/O voodoo;
- no need to s/mdio_write/RTL8169_WRITE_GMII_REG/;
- s/rtl8169_hw_PHY_config/rtl8169_hw_phy_config/;
- rtl8169_hw_phy_config(): ad-hoc struct "phy_magic" to limit duplication of code (yep, the u16 -> int conversions should work as expected);
- variable renames and whitepace changes ignored.

As the 8168 wasn't supported by that version this patch simply removes the bogus write from mac versions <= RTL_GIGA_MAC_VER_06.

[The change above makes sense for the 8101/8102 too -- Ueimor]

---
 drivers/net/r8169.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/r8169.c +4 -2
@@ -1438,8 +1438,10 @@ static void rtl8169_init_phy(struct net_
 
 	rtl_hw_phy_config(dev);
 
-	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
-	RTL_W8(0x82, 0x01);
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_06) {
+		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
+		RTL_W8(0x82, 0x01);
+	}
 
 	pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
 
author
#106 lore raw

PATCH 43/49 netfilter: nf_nat_snmp_basic: fix a range check in NAT for SNMP

In reply to Greg KH

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

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

From: David Howells <[email protected]>

commit 252815b0cfe711001eff0327872209986b36d490 upstream

Fix a range check in netfilter IP NAT for SNMP to always use a big enough size variable that the compiler won't moan about comparing it to ULONG_MAX/8 on a 64-bit platform.

---
 net/ipv4/netfilter/nf_nat_snmp_basic.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/netfilter/nf_nat_snmp_basic.c +1 -1
@@ -438,8 +438,8 @@ static unsigned char asn1_oid_decode(str
 				     unsigned int *len)
 {
 	unsigned long subid;
-	unsigned int  size;
 	unsigned long *optr;
+	size_t size;
 
 	size = eoc - ctx->pointer + 1;
 
author
#107 lore raw

PATCH 44/49 i2c: Fix NULL pointer dereference in i2c_new_probed_device

In reply to Greg KH

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

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

From: Hans Verkuil <[email protected]>

Already in Linus' tree:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b25b791b13aaa336b56c4f9bd417ff126363f80b

Fix a NULL pointer dereference that happened when calling i2c_new_probed_device on one of the addresses for which we use byte reads instead of quick write for detection purpose (that is: 0x30-0x37 and 0x50-0x5f).

---
 drivers/i2c/i2c-core.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/i2c/i2c-core.c +3 -1
@@ -1173,9 +1173,11 @@ i2c_new_probed_device(struct i2c_adapter
 		if ((addr_list[i] & ~0x07) == 0x30
 		 || (addr_list[i] & ~0x0f) == 0x50
 		 || !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK)) {
+			union i2c_smbus_data data;
+
 			if (i2c_smbus_xfer(adap, addr_list[i], 0,
 					   I2C_SMBUS_READ, 0,
-					   I2C_SMBUS_BYTE, NULL) >= 0)
+					   I2C_SMBUS_BYTE, &data) >= 0)
 				break;
 		} else {
 			if (i2c_smbus_xfer(adap, addr_list[i], 0,
author
#108 lore raw

PATCH 45/49 CIFS: Fix compiler warning on 64-bit

In reply to Greg KH

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

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

From: Jan Beulich <[email protected]>

commit 04e1e0cccade330ab3715ce59234f7e3b087e246 upstream.

---
 fs/cifs/asn1.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
fs/cifs/asn1.c +1 -1
@@ -400,7 +400,7 @@ asn1_oid_decode(struct asn1_ctx *ctx,
 	size = eoc - ctx->pointer + 1;
 
 	/* first subid actually encodes first two subids */
-	if (size < 2 || size > ULONG_MAX/sizeof(unsigned long))
+	if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
 		return 0;
 
 	*oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
author
#109 lore raw

PATCH 46/49 x86: fix spin_is_contended()

In reply to Greg KH

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

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

From: Jan Beulich <[email protected]>

commit 7bc069c6bc4ede519a7116be1b9e149a1dbf787a upstream

The masked difference is what needs to be compared against 1, rather than the difference of masked values (which can be negative).

---
 include/asm-x86/spinlock.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
include/asm-x86/spinlock.h +2 -2
@@ -75,7 +75,7 @@ static inline int __raw_spin_is_contende
 {
 	int tmp = *(volatile signed int *)(&(lock)->slock);
 
-	return (((tmp >> 8) & 0xff) - (tmp & 0xff)) > 1;
+	return (((tmp >> 8) - tmp) & 0xff) > 1;
 }
 
 static inline void __raw_spin_lock(raw_spinlock_t *lock)
@@ -141,7 +141,7 @@ static inline int __raw_spin_is_contende
 {
 	int tmp = *(volatile signed int *)(&(lock)->slock);
 
-	return (((tmp >> 16) & 0xffff) - (tmp & 0xffff)) > 1;
+	return (((tmp >> 16) - tmp) & 0xffff) > 1;
 }
 
 static inline void __raw_spin_lock(raw_spinlock_t *lock)
author
#110 lore raw

PATCH 47/49 x86: fix setup code crashes on my old 486 box

In reply to Greg KH

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

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

From: Joerg Roedel <[email protected]>

commit 7b27718bdb1b70166383dec91391df5534d449ee upstream

yesterday I tried to reactivate my old 486 box and wanted to install a current Linux with latest kernel on it. But it turned out that the latest kernel does not boot because the machine crashes early in the setup code.

After some debugging it turned out that the problem is the query_ist() function. If this interrupt with that function is called the machine simply locks up. It looks like a BIOS bug. Looking for a workaround for this problem I wrote the attached patch. It checks for the CPUID instruction and if it is not implemented it does not call the speedstep BIOS function. As far as I know speedstep should be available since some Pentium earliest.

Alan Cox observed that it's available since the Pentium II, so cpuid levels 4 and 5 can be excluded altogether.

H. Peter Anvin cleaned up the code some more:

Quoted 3 lines

Right in concept, but I dislike the implementation (duplication of the CPU detect code we already have). Could you try this patch and see if it works for you?

which, with a small modification to fix a build error with it the resulting kernel boots on my machine.

---
 arch/x86/boot/boot.h     |    8 ++++++++
 arch/x86/boot/cpucheck.c |    8 +-------
 arch/x86/boot/main.c     |    4 ++++
 3 files changed, 13 insertions(+), 7 deletions(-)
arch/x86/boot/boot.h +8 -0
@@ -27,6 +27,8 @@
 #include <asm/boot.h>
 #include <asm/setup.h>
 
+#define NCAPINTS   8
+
 /* Useful macros */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
@@ -244,6 +246,12 @@ int cmdline_find_option(const char *opti
 int cmdline_find_option_bool(const char *option);
 
 /* cpu.c, cpucheck.c */
+struct cpu_features {
+	int level;		/* Family, or 64 for x86-64 */
+	int model;
+	u32 flags[NCAPINTS];
+};
+extern struct cpu_features cpu;
 int check_cpu(int *cpu_level_ptr, int *req_level_ptr, u32 **err_flags_ptr);
 int validate_cpu(void);
 
arch/x86/boot/cpucheck.c +1 -7
@@ -32,13 +32,7 @@
 #include <asm/required-features.h>
 #include <asm/msr-index.h>
 
-struct cpu_features {
-	int level;		/* Family, or 64 for x86-64 */
-	int model;
-	u32 flags[NCAPINTS];
-};
-
-static struct cpu_features cpu;
+struct cpu_features cpu;
 static u32 cpu_vendor[3];
 static u32 err_flags[NCAPINTS];
 
arch/x86/boot/main.c +4 -0
@@ -75,6 +75,10 @@ static void keyboard_set_repeat(void)
  */
 static void query_ist(void)
 {
+	/* Some 486 BIOSes apparently crash on this call */
+	if (cpu.level < 6)
+		return;
+
 	asm("int $0x15"
 	    : "=a" (boot_params.ist_info.signature),
 	      "=b" (boot_params.ist_info.command),
author
#111 lore raw

PATCH 48/49 qla2xxx: Add dev_loss_tmo_callbk/terminate_rport_io callback support.

In reply to Greg KH

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

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

From: Seokmann Ju <[email protected]>

[ Upstream commit 5f3a9a207f1fccde476dd31b4c63ead2967d934f ]

---
 drivers/scsi/qla2xxx/qla_attr.c |   31 +++++++++++++++++++++++
 drivers/scsi/qla2xxx/qla_def.h  |    1 
 drivers/scsi/qla2xxx/qla_gbl.h  |    2 +
 drivers/scsi/qla2xxx/qla_init.c |   16 +++---------
 drivers/scsi/qla2xxx/qla_os.c   |   53 ++++++++++++++++++++++++++++++----------
 5 files changed, 78 insertions(+), 25 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +31 -0
@@ -969,6 +969,33 @@ qla2x00_set_rport_loss_tmo(struct fc_rpo
 	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
 }
 
+static void
+qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
+{
+	struct Scsi_Host *host = rport_to_shost(rport);
+	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+	qla2x00_abort_fcport_cmds(fcport);
+
+	/*
+	 * Transport has effectively 'deleted' the rport, clear
+	 * all local references.
+	 */
+	spin_lock_irq(host->host_lock);
+	fcport->rport = NULL;
+	*((fc_port_t **)rport->dd_data) = NULL;
+	spin_unlock_irq(host->host_lock);
+}
+
+static void
+qla2x00_terminate_rport_io(struct fc_rport *rport)
+{
+	fc_port_t *fcport = *(fc_port_t **)rport->dd_data;
+
+	qla2x00_abort_fcport_cmds(fcport);
+	scsi_target_unblock(&rport->dev);
+}
+
 static int
 qla2x00_issue_lip(struct Scsi_Host *shost)
 {
@@ -1227,6 +1254,8 @@ struct fc_function_template qla2xxx_tran
 	.show_rport_dev_loss_tmo = 1,
 
 	.issue_fc_host_lip = qla2x00_issue_lip,
+	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
 
 	.vport_create = qla24xx_vport_create,
@@ -1270,6 +1299,8 @@ struct fc_function_template qla2xxx_tran
 	.show_rport_dev_loss_tmo = 1,
 
 	.issue_fc_host_lip = qla2x00_issue_lip,
+	.dev_loss_tmo_callbk = qla2x00_dev_loss_tmo_callbk,
+	.terminate_rport_io = qla2x00_terminate_rport_io,
 	.get_fc_host_stats = qla2x00_get_fc_host_stats,
 };
 
drivers/scsi/qla2xxx/qla_def.h +0 -1
@@ -1548,7 +1548,6 @@ typedef struct fc_port {
 	int login_retry;
 	atomic_t port_down_timer;
 
-	spinlock_t rport_lock;
 	struct fc_rport *rport, *drport;
 	u32 supported_classes;
 
drivers/scsi/qla2xxx/qla_gbl.h +2 -0
@@ -68,6 +68,8 @@ extern int num_hosts;
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
 
+extern void qla2x00_abort_fcport_cmds(fc_port_t *);
+
 /*
  * Global Functions in qla_mid.c source file.
  */
drivers/scsi/qla2xxx/qla_init.c +5 -11
@@ -1827,12 +1827,11 @@ qla2x00_rport_del(void *data)
 {
 	fc_port_t *fcport = data;
 	struct fc_rport *rport;
-	unsigned long flags;
 
-	spin_lock_irqsave(&fcport->rport_lock, flags);
+	spin_lock_irq(fcport->ha->host->host_lock);
 	rport = fcport->drport;
 	fcport->drport = NULL;
-	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+	spin_unlock_irq(fcport->ha->host->host_lock);
 	if (rport)
 		fc_remote_port_delete(rport);
 }
@@ -1861,7 +1860,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha
 	atomic_set(&fcport->state, FCS_UNCONFIGURED);
 	fcport->flags = FCF_RLC_SUPPORT;
 	fcport->supported_classes = FC_COS_UNSPECIFIED;
-	spin_lock_init(&fcport->rport_lock);
 
 	return fcport;
 }
@@ -2220,28 +2218,24 @@ qla2x00_reg_remote_port(scsi_qla_host_t 
 {
 	struct fc_rport_identifiers rport_ids;
 	struct fc_rport *rport;
-	unsigned long flags;
 
 	if (fcport->drport)
 		qla2x00_rport_del(fcport);
-	if (fcport->rport)
-		return;
 
 	rport_ids.node_name = wwn_to_u64(fcport->node_name);
 	rport_ids.port_name = wwn_to_u64(fcport->port_name);
 	rport_ids.port_id = fcport->d_id.b.domain << 16 |
 	    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 	rport_ids.roles = FC_RPORT_ROLE_UNKNOWN;
-	rport = fc_remote_port_add(ha->host, 0, &rport_ids);
+	fcport->rport = rport = fc_remote_port_add(ha->host, 0, &rport_ids);
 	if (!rport) {
 		qla_printk(KERN_WARNING, ha,
 		    "Unable to allocate fc remote port!\n");
 		return;
 	}
-	spin_lock_irqsave(&fcport->rport_lock, flags);
-	fcport->rport = rport;
+	spin_lock_irq(fcport->ha->host->host_lock);
 	*((fc_port_t **)rport->dd_data) = fcport;
-	spin_unlock_irqrestore(&fcport->rport_lock, flags);
+	spin_unlock_irq(fcport->ha->host->host_lock);
 
 	rport->supported_classes = fcport->supported_classes;
 
drivers/scsi/qla2xxx/qla_os.c +40 -13

86 lines not on this page · raw message

author
#112 lore raw

PATCH 49/49 qla2xxx: Set an rports dev_loss_tmo value in a consistent manner.

In reply to Greg KH

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

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

From: Andrew Vasquez <[email protected]>

[ Upstream commit 85821c906cf3563a00a3d98fa380a2581a7a5ff1 ]

As there's no point in adding a fixed-fudge value (originally 5 seconds), honor the user settings only. We also remove the driver's dead-callback get_rport_dev_loss_tmo function (qla2x00_get_rport_loss_tmo()).

---
 drivers/scsi/qla2xxx/qla_attr.c |   20 ++------------------
 drivers/scsi/qla2xxx/qla_os.c   |    2 +-
 2 files changed, 3 insertions(+), 19 deletions(-)
drivers/scsi/qla2xxx/qla_attr.c +2 -18
@@ -947,26 +947,12 @@ qla2x00_get_starget_port_id(struct scsi_
 }
 
 static void
-qla2x00_get_rport_loss_tmo(struct fc_rport *rport)
-{
-	struct Scsi_Host *host = rport_to_shost(rport);
-	scsi_qla_host_t *ha = shost_priv(host);
-
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
-}
-
-static void
 qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout)
 {
-	struct Scsi_Host *host = rport_to_shost(rport);
-	scsi_qla_host_t *ha = shost_priv(host);
-
 	if (timeout)
-		ha->port_down_retry_count = timeout;
+		rport->dev_loss_tmo = timeout;
 	else
-		ha->port_down_retry_count = 1;
-
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+		rport->dev_loss_tmo = 1;
 }
 
 static void
@@ -1249,7 +1235,6 @@ struct fc_function_template qla2xxx_tran
 	.get_starget_port_id  = qla2x00_get_starget_port_id,
 	.show_starget_port_id = 1,
 
-	.get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
 	.show_rport_dev_loss_tmo = 1,
 
@@ -1294,7 +1279,6 @@ struct fc_function_template qla2xxx_tran
 	.get_starget_port_id  = qla2x00_get_starget_port_id,
 	.show_starget_port_id = 1,
 
-	.get_rport_dev_loss_tmo = qla2x00_get_rport_loss_tmo,
 	.set_rport_dev_loss_tmo = qla2x00_set_rport_loss_tmo,
 	.show_rport_dev_loss_tmo = 1,
 
drivers/scsi/qla2xxx/qla_os.c +1 -1
@@ -1194,7 +1194,7 @@ qla2xxx_slave_configure(struct scsi_devi
 	else
 		scsi_deactivate_tcq(sdev, ha->max_q_depth);
 
-	rport->dev_loss_tmo = ha->port_down_retry_count + 5;
+	rport->dev_loss_tmo = ha->port_down_retry_count;
 
 	return 0;
 }