]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.32 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Mon, 6 Dec 2010 20:59:04 +0000 (12:59 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Mon, 6 Dec 2010 20:59:04 +0000 (12:59 -0800)
queue-2.6.32/efifb-check-that-the-base-address-is-plausible-on-pci-systems.patch [new file with mode: 0644]
queue-2.6.32/libata-fix-null-sdev-dereference-race-in-atapi_qc_complete.patch [new file with mode: 0644]
queue-2.6.32/libata-scsi-passthru-fix-bug-which-truncated-lba48-return-values.patch [new file with mode: 0644]
queue-2.6.32/pci-fix-offset-check-for-sysfs-mmapped-files.patch [new file with mode: 0644]
queue-2.6.32/pci-fix-size-checks-for-mmap-on-proc-bus-pci-files.patch [new file with mode: 0644]
queue-2.6.32/series

diff --git a/queue-2.6.32/efifb-check-that-the-base-address-is-plausible-on-pci-systems.patch b/queue-2.6.32/efifb-check-that-the-base-address-is-plausible-on-pci-systems.patch
new file mode 100644 (file)
index 0000000..82a172e
--- /dev/null
@@ -0,0 +1,141 @@
+From 85a00d9bbfb4704fbf368944b1cb9fed8f1598c5 Mon Sep 17 00:00:00 2001
+From: Peter Jones <pjones@redhat.com>
+Date: Wed, 22 Sep 2010 13:05:04 -0700
+Subject: efifb: check that the base address is plausible on pci systems
+
+From: Peter Jones <pjones@redhat.com>
+
+commit 85a00d9bbfb4704fbf368944b1cb9fed8f1598c5 upstream.
+
+Some Apple machines have identical DMI data but different memory
+configurations for the video.  Given that, check that the address in our
+table is actually within the range of a PCI BAR on a VGA device in the
+machine.
+
+This also fixes up the return value from set_system(), which has always
+been wrong, but never resulted in bad behavior since there's only ever
+been one matching entry in the dmi table.
+
+The patch
+
+1) stops people's machines from crashing when we get their display wrong,
+   which seems to be unfortunately inevitable,
+
+2) allows us to support identical dmi data with differing video memory
+   configurations
+
+This also adds me as the efifb maintainer, since I've effectively been
+acting as such for quite some time.
+
+Signed-off-by: Peter Jones <pjones@redhat.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: maximilian attems <max@stro.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ MAINTAINERS           |    6 ++++
+ drivers/video/efifb.c |   61 ++++++++++++++++++++++++++++++++++++++++----------
+ 2 files changed, 55 insertions(+), 12 deletions(-)
+
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -1974,6 +1974,12 @@ W:      http://acpi4asus.sf.net
+ S:    Maintained
+ F:    drivers/platform/x86/eeepc-laptop.c
++EFIFB FRAMEBUFFER DRIVER
++L:    linux-fbdev@vger.kernel.org
++M:    Peter Jones <pjones@redhat.com>
++S:    Maintained
++F:    drivers/video/efifb.c
++
+ EFS FILESYSTEM
+ W:    http://aeschi.ch.eu.org/efs/
+ S:    Orphan
+--- a/drivers/video/efifb.c
++++ b/drivers/video/efifb.c
+@@ -13,7 +13,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/screen_info.h>
+ #include <linux/dmi.h>
+-
++#include <linux/pci.h>
+ #include <video/vga.h>
+ static struct fb_var_screeninfo efifb_defined __initdata = {
+@@ -113,7 +113,7 @@ static int set_system(const struct dmi_s
+ {
+       struct efifb_dmi_info *info = id->driver_data;
+       if (info->base == 0)
+-              return -ENODEV;
++              return 0;
+       printk(KERN_INFO "efifb: dmi detected %s - framebuffer at %p "
+                        "(%dx%d, stride %d)\n", id->ident,
+@@ -121,18 +121,55 @@ static int set_system(const struct dmi_s
+                        info->stride);
+       /* Trust the bootloader over the DMI tables */
+-      if (screen_info.lfb_base == 0)
++      if (screen_info.lfb_base == 0) {
++#if defined(CONFIG_PCI)
++              struct pci_dev *dev = NULL;
++              int found_bar = 0;
++#endif
+               screen_info.lfb_base = info->base;
+-      if (screen_info.lfb_linelength == 0)
+-              screen_info.lfb_linelength = info->stride;
+-      if (screen_info.lfb_width == 0)
+-              screen_info.lfb_width = info->width;
+-      if (screen_info.lfb_height == 0)
+-              screen_info.lfb_height = info->height;
+-      if (screen_info.orig_video_isVGA == 0)
+-              screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
+-      return 0;
++#if defined(CONFIG_PCI)
++              /* make sure that the address in the table is actually on a
++               * VGA device's PCI BAR */
++
++              for_each_pci_dev(dev) {
++                      int i;
++                      if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
++                              continue;
++                      for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
++                              resource_size_t start, end;
++
++                              start = pci_resource_start(dev, i);
++                              if (start == 0)
++                                      break;
++                              end = pci_resource_end(dev, i);
++                              if (screen_info.lfb_base >= start &&
++                                              screen_info.lfb_base < end) {
++                                      found_bar = 1;
++                              }
++                      }
++              }
++              if (!found_bar)
++                      screen_info.lfb_base = 0;
++#endif
++      }
++      if (screen_info.lfb_base) {
++              if (screen_info.lfb_linelength == 0)
++                      screen_info.lfb_linelength = info->stride;
++              if (screen_info.lfb_width == 0)
++                      screen_info.lfb_width = info->width;
++              if (screen_info.lfb_height == 0)
++                      screen_info.lfb_height = info->height;
++              if (screen_info.orig_video_isVGA == 0)
++                      screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
++      } else {
++              screen_info.lfb_linelength = 0;
++              screen_info.lfb_width = 0;
++              screen_info.lfb_height = 0;
++              screen_info.orig_video_isVGA = 0;
++              return 0;
++      }
++      return 1;
+ }
+ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
diff --git a/queue-2.6.32/libata-fix-null-sdev-dereference-race-in-atapi_qc_complete.patch b/queue-2.6.32/libata-fix-null-sdev-dereference-race-in-atapi_qc_complete.patch
new file mode 100644 (file)
index 0000000..d789e08
--- /dev/null
@@ -0,0 +1,36 @@
+From 2a5f07b5ec098edc69e05fdd2f35d3fbb1235723 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 1 Nov 2010 11:39:19 +0100
+Subject: libata: fix NULL sdev dereference race in atapi_qc_complete()
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 2a5f07b5ec098edc69e05fdd2f35d3fbb1235723 upstream.
+
+SCSI commands may be issued between __scsi_add_device() and dev->sdev
+assignment, so it's unsafe for ata_qc_complete() to dereference
+dev->sdev->locked without checking whether it's NULL or not.  Fix it.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/libata-scsi.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -2497,8 +2497,11 @@ static void atapi_qc_complete(struct ata
+                *
+                * If door lock fails, always clear sdev->locked to
+                * avoid this infinite loop.
++               *
++               * This may happen before SCSI scan is complete.  Make
++               * sure qc->dev->sdev isn't NULL before dereferencing.
+                */
+-              if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL)
++              if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev)
+                       qc->dev->sdev->locked = 0;
+               qc->scsicmd->result = SAM_STAT_CHECK_CONDITION;
diff --git a/queue-2.6.32/libata-scsi-passthru-fix-bug-which-truncated-lba48-return-values.patch b/queue-2.6.32/libata-scsi-passthru-fix-bug-which-truncated-lba48-return-values.patch
new file mode 100644 (file)
index 0000000..8d6bdbd
--- /dev/null
@@ -0,0 +1,32 @@
+From bc496ed00ab1411d3efaf295b72e0c9eb343e1a3 Mon Sep 17 00:00:00 2001
+From: Douglas Gilbert <dgilbert@interlog.com>
+Date: Mon, 1 Feb 2010 13:11:38 -0500
+Subject: libata-scsi passthru: fix bug which truncated LBA48 return values
+
+From: Douglas Gilbert <dgilbert@interlog.com>
+
+commit bc496ed00ab1411d3efaf295b72e0c9eb343e1a3 upstream.
+
+Fix assignment which overwrote SAT ATA PASS-THROUGH command EXTEND
+bit setting (ATA_TFLAG_LBA48)
+
+Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
+Cc: Kerin Millar <kerframil@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/libata-scsi.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -2825,7 +2825,7 @@ static unsigned int ata_scsi_pass_thru(s
+        * write indication (used for PIO/DMA setup), result TF is
+        * copied back and we don't whine too much about its failure.
+        */
+-      tf->flags = ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
++      tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+       if (scmd->sc_data_direction == DMA_TO_DEVICE)
+               tf->flags |= ATA_TFLAG_WRITE;
diff --git a/queue-2.6.32/pci-fix-offset-check-for-sysfs-mmapped-files.patch b/queue-2.6.32/pci-fix-offset-check-for-sysfs-mmapped-files.patch
new file mode 100644 (file)
index 0000000..2f4cfee
--- /dev/null
@@ -0,0 +1,63 @@
+From 8c05cd08a7504b855c265263e84af61aabafa329 Mon Sep 17 00:00:00 2001
+From: Darrick J. Wong <djwong@us.ibm.com>
+Date: Tue, 16 Nov 2010 09:13:41 -0800
+Subject: PCI: fix offset check for sysfs mmapped files
+
+From: Darrick J. Wong <djwong@us.ibm.com>
+
+commit 8c05cd08a7504b855c265263e84af61aabafa329 upstream.
+
+I just loaded 2.6.37-rc2 on my machines, and I noticed that X no longer starts.
+Running an strace of the X server shows that it's doing this:
+
+open("/sys/bus/pci/devices/0000:07:00.0/resource0", O_RDWR) = 10
+mmap(NULL, 16777216, PROT_READ|PROT_WRITE, MAP_SHARED, 10, 0) = -1 EINVAL (Invalid argument)
+
+This code seems to be asking for a shared read/write mapping of 16MB worth of
+BAR0 starting at file offset 0, and letting the kernel assign a starting
+address.  Unfortunately, this -EINVAL causes X not to start.  Looking into
+dmesg, there's a complaint like so:
+
+process "Xorg" tried to map 0x01000000 bytes at page 0x00000000 on 0000:07:00.0 BAR 0 (start 0x        96000000, size 0x         1000000)
+
+...with the following code in pci_mmap_fits:
+
+       pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
+               pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+        if (start >= pci_start && start < pci_start + size &&
+                        start + nr <= pci_start + size)
+
+It looks like the logic here is set up such that when the mmap call comes via
+sysfs, the check in pci_mmap_fits wants vma->vm_pgoff to be between the
+resource's start and end address, and the end of the vma to be no farther than
+the end.  However, the sysfs PCI resource files always start at offset zero,
+which means that this test always fails for programs that mmap the sysfs files.
+Given the comment in the original commit
+3b519e4ea618b6943a82931630872907f9ac2c2b, I _think_ the old procfs files
+require that the file offset be equal to the resource's base address when
+mmapping.
+
+I think what we want here is for pci_start to be 0 when mmap_api ==
+PCI_MMAP_PROCFS.  The following patch makes that change, after which the Matrox
+and Mach64 X drivers work again.
+
+Acked-by: Martin Wilck <martin.wilck@ts.fujitsu.com>
+Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pci-sysfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -672,7 +672,7 @@ int pci_mmap_fits(struct pci_dev *pdev,
+       nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+       start = vma->vm_pgoff;
+       size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
+-      pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
++      pci_start = (mmap_api == PCI_MMAP_PROCFS) ?
+                       pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
+       if (start >= pci_start && start < pci_start + size &&
+                       start + nr <= pci_start + size)
diff --git a/queue-2.6.32/pci-fix-size-checks-for-mmap-on-proc-bus-pci-files.patch b/queue-2.6.32/pci-fix-size-checks-for-mmap-on-proc-bus-pci-files.patch
new file mode 100644 (file)
index 0000000..0910a51
--- /dev/null
@@ -0,0 +1,118 @@
+From 3b519e4ea618b6943a82931630872907f9ac2c2b Mon Sep 17 00:00:00 2001
+From: Martin Wilck <martin.wilck@ts.fujitsu.com>
+Date: Wed, 10 Nov 2010 11:03:21 +0100
+Subject: PCI: fix size checks for mmap() on /proc/bus/pci files
+
+From: Martin Wilck <martin.wilck@ts.fujitsu.com>
+
+commit 3b519e4ea618b6943a82931630872907f9ac2c2b upstream.
+
+The checks for valid mmaps of PCI resources made through /proc/bus/pci files
+that were introduced in 9eff02e2042f96fb2aedd02e032eca1c5333d767 have several
+problems:
+
+1. mmap() calls on /proc/bus/pci files are made with real file offsets > 0,
+whereas under /sys/bus/pci/devices, the start of the resource corresponds
+to offset 0. This may lead to false negatives in pci_mmap_fits(), which
+implicitly assumes the /sys/bus/pci/devices layout.
+
+2. The loop in proc_bus_pci_mmap doesn't skip empty resouces. This leads
+to false positives, because pci_mmap_fits() doesn't treat empty resources
+correctly (the calculated size is 1 << (8*sizeof(resource_size_t)-PAGE_SHIFT)
+in this case!).
+
+3. If a user maps resources with BAR > 0, pci_mmap_fits will emit bogus
+WARNINGS for the first resources that don't fit until the correct one is found.
+
+On many controllers the first 2-4 BARs are used, and the others are empty.
+In this case, an mmap attempt will first fail on the non-empty BARs
+(including the "right" BAR because of 1.) and emit bogus WARNINGS because
+of 3., and finally succeed on the first empty BAR because of 2.
+This is certainly not the intended behaviour.
+
+This patch addresses all 3 issues.
+Updated with an enum type for the additional parameter for pci_mmap_fits().
+
+Signed-off-by: Martin Wilck <martin.wilck@ts.fujitsu.com>
+Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/pci/pci-sysfs.c |   22 ++++++++++++++++------
+ drivers/pci/pci.h       |    7 ++++++-
+ drivers/pci/proc.c      |    2 +-
+ 3 files changed, 23 insertions(+), 8 deletions(-)
+
+--- a/drivers/pci/pci-sysfs.c
++++ b/drivers/pci/pci-sysfs.c
+@@ -662,17 +662,21 @@ void pci_remove_legacy_files(struct pci_
+ #ifdef HAVE_PCI_MMAP
+-int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma)
++int pci_mmap_fits(struct pci_dev *pdev, int resno, struct vm_area_struct *vma,
++                enum pci_mmap_api mmap_api)
+ {
+-      unsigned long nr, start, size;
++      unsigned long nr, start, size, pci_start;
++      if (pci_resource_len(pdev, resno) == 0)
++              return 0;
+       nr = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+       start = vma->vm_pgoff;
+       size = ((pci_resource_len(pdev, resno) - 1) >> PAGE_SHIFT) + 1;
+-      if (start < size && size - start >= nr)
++      pci_start = (mmap_api == PCI_MMAP_SYSFS) ?
++                      pci_resource_start(pdev, resno) >> PAGE_SHIFT : 0;
++      if (start >= pci_start && start < pci_start + size &&
++                      start + nr <= pci_start + size)
+               return 1;
+-      WARN(1, "process \"%s\" tried to map 0x%08lx-0x%08lx on %s BAR %d (size 0x%08lx)\n",
+-              current->comm, start, start+nr, pci_name(pdev), resno, size);
+       return 0;
+ }
+@@ -702,8 +706,14 @@ pci_mmap_resource(struct kobject *kobj,
+       if (i >= PCI_ROM_RESOURCE)
+               return -ENODEV;
+-      if (!pci_mmap_fits(pdev, i, vma))
++      if (!pci_mmap_fits(pdev, i, vma, PCI_MMAP_SYSFS)) {
++              WARN(1, "process \"%s\" tried to map 0x%08lx bytes "
++                      "at page 0x%08lx on %s BAR %d (start 0x%16Lx, size 0x%16Lx)\n",
++                      current->comm, vma->vm_end-vma->vm_start, vma->vm_pgoff,
++                      pci_name(pdev), i,
++                      pci_resource_start(pdev, i), pci_resource_len(pdev, i));
+               return -EINVAL;
++      }
+       /* pci_mmap_page_range() expects the same kind of entry as coming
+        * from /proc/bus/pci/ which is a "user visible" value. If this is
+--- a/drivers/pci/pci.h
++++ b/drivers/pci/pci.h
+@@ -13,8 +13,13 @@ extern int pci_create_sysfs_dev_files(st
+ extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
+ extern void pci_cleanup_rom(struct pci_dev *dev);
+ #ifdef HAVE_PCI_MMAP
++enum pci_mmap_api {
++      PCI_MMAP_SYSFS, /* mmap on /sys/bus/pci/devices/<BDF>/resource<N> */
++      PCI_MMAP_PROCFS /* mmap on /proc/bus/pci/<BDF> */
++};
+ extern int pci_mmap_fits(struct pci_dev *pdev, int resno,
+-                       struct vm_area_struct *vma);
++                       struct vm_area_struct *vmai,
++                       enum pci_mmap_api mmap_api);
+ #endif
+ int pci_probe_reset_function(struct pci_dev *dev);
+--- a/drivers/pci/proc.c
++++ b/drivers/pci/proc.c
+@@ -259,7 +259,7 @@ static int proc_bus_pci_mmap(struct file
+       /* Make sure the caller is mapping a real resource for this device */
+       for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+-              if (pci_mmap_fits(dev, i, vma))
++              if (pci_mmap_fits(dev, i, vma,  PCI_MMAP_PROCFS))
+                       break;
+       }
index 4974f08093b33e7708065551612bcd271dc6d1e8..465180539c663a2aff1c9f072c3752e68f418c28 100644 (file)
@@ -57,3 +57,8 @@ latencytop-fix-per-task-accumulator.patch
 mm-vfs-revalidate-page-mapping-in-do_generic_file_read.patch
 bio-take-care-not-overflow-page-count-when-mapping-copying-user-data.patch
 drm-ttm-clear-the-ghost-cpu_writers-flag-on-ttm_buffer_object_transfer.patch
+libata-scsi-passthru-fix-bug-which-truncated-lba48-return-values.patch
+libata-fix-null-sdev-dereference-race-in-atapi_qc_complete.patch
+pci-fix-size-checks-for-mmap-on-proc-bus-pci-files.patch
+pci-fix-offset-check-for-sysfs-mmapped-files.patch
+efifb-check-that-the-base-address-is-plausible-on-pci-systems.patch