From 3aa4d7a753a21d80a8e20992fa653165a8fa7abd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 15 Dec 2009 15:50:14 -0800 Subject: [PATCH] .27 patches --- ...ate-mutex-racy-fops-and-private-data.patch | 169 +++++++++++++++++ ...e-packets-with-a-data-length-of-zero.patch | 59 ++++++ ...ct-o_direct-flag-also-in-fuse_create.patch | 43 +++++ .../hfs-fix-a-potential-buffer-overflow.patch | 95 ++++++++++ ...x2n-fix-timing-register-masks-take-2.patch | 173 ++++++++++++++++++ queue-2.6.27/series | 12 ++ .../ssb-fix-range-check-in-sprom-write.patch | 66 +++++++ .../v4l-dvb-fix-test-in-copy_reg_bits.patch | 32 ++++ ...lapic-nmi-watchdog-on-amd-family-11h.patch | 47 +++++ .../x86-asus-p4s800-reboot-bios-quirk.patch | 63 +++++++ ...algary-while-walking-up-the-pci-tree.patch | 83 +++++++++ ...6-fix-iommu-nodac-parameter-handling.patch | 33 ++++ ...t_64.c-use-correct-length-in-strncmp.patch | 29 +++ 13 files changed, 904 insertions(+) create mode 100644 queue-2.6.27/debugfs-fix-create-mutex-racy-fops-and-private-data.patch create mode 100644 queue-2.6.27/firewire-ohci-handle-receive-packets-with-a-data-length-of-zero.patch create mode 100644 queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch create mode 100644 queue-2.6.27/hfs-fix-a-potential-buffer-overflow.patch create mode 100644 queue-2.6.27/pata_hpt-37x-3x2n-fix-timing-register-masks-take-2.patch create mode 100644 queue-2.6.27/ssb-fix-range-check-in-sprom-write.patch create mode 100644 queue-2.6.27/v4l-dvb-fix-test-in-copy_reg_bits.patch create mode 100644 queue-2.6.27/x86-apic-enable-lapic-nmi-watchdog-on-amd-family-11h.patch create mode 100644 queue-2.6.27/x86-asus-p4s800-reboot-bios-quirk.patch create mode 100644 queue-2.6.27/x86-calgary-iommu-quirk-find-nearest-matching-calgary-while-walking-up-the-pci-tree.patch create mode 100644 queue-2.6.27/x86-fix-iommu-nodac-parameter-handling.patch create mode 100644 queue-2.6.27/x86-gart-pci-gart_64.c-use-correct-length-in-strncmp.patch diff --git a/queue-2.6.27/debugfs-fix-create-mutex-racy-fops-and-private-data.patch b/queue-2.6.27/debugfs-fix-create-mutex-racy-fops-and-private-data.patch new file mode 100644 index 00000000000..5bb08d47843 --- /dev/null +++ b/queue-2.6.27/debugfs-fix-create-mutex-racy-fops-and-private-data.patch @@ -0,0 +1,169 @@ +From d3a3b0adad0865c12e39b712ca89efbd0a3a0dbc Mon Sep 17 00:00:00 2001 +From: Mathieu Desnoyers +Date: Tue, 17 Nov 2009 14:40:26 -0800 +Subject: debugfs: fix create mutex racy fops and private data + +From: Mathieu Desnoyers + +commit d3a3b0adad0865c12e39b712ca89efbd0a3a0dbc upstream. + +Setting fops and private data outside of the mutex at debugfs file +creation introduces a race where the files can be opened with the wrong +file operations and private data. It is easy to trigger with a process +waiting on file creation notification. + +Signed-off-by: Mathieu Desnoyers +Signed-off-by: Andrew Morton +Signed-off-by: Greg Kroah-Hartman + +--- + fs/debugfs/inode.c | 55 ++++++++++++++++++++++++++++++----------------------- + 1 file changed, 32 insertions(+), 23 deletions(-) + +--- a/fs/debugfs/inode.c ++++ b/fs/debugfs/inode.c +@@ -32,7 +32,9 @@ + static struct vfsmount *debugfs_mount; + static int debugfs_mount_count; + +-static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev) ++static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t dev, ++ void *data, const struct file_operations *fops) ++ + { + struct inode *inode = new_inode(sb); + +@@ -47,14 +49,18 @@ static struct inode *debugfs_get_inode(s + init_special_inode(inode, mode, dev); + break; + case S_IFREG: +- inode->i_fop = &debugfs_file_operations; ++ inode->i_fop = fops ? fops : &debugfs_file_operations; ++ inode->i_private = data; + break; + case S_IFLNK: + inode->i_op = &debugfs_link_operations; ++ inode->i_fop = fops; ++ inode->i_private = data; + break; + case S_IFDIR: + inode->i_op = &simple_dir_inode_operations; +- inode->i_fop = &simple_dir_operations; ++ inode->i_fop = fops ? fops : &simple_dir_operations; ++ inode->i_private = data; + + /* directory inodes start off with i_nlink == 2 + * (for "." entry) */ +@@ -67,7 +73,8 @@ static struct inode *debugfs_get_inode(s + + /* SMP-safe */ + static int debugfs_mknod(struct inode *dir, struct dentry *dentry, +- int mode, dev_t dev) ++ int mode, dev_t dev, void *data, ++ const struct file_operations *fops) + { + struct inode *inode; + int error = -EPERM; +@@ -75,7 +82,7 @@ static int debugfs_mknod(struct inode *d + if (dentry->d_inode) + return -EEXIST; + +- inode = debugfs_get_inode(dir->i_sb, mode, dev); ++ inode = debugfs_get_inode(dir->i_sb, mode, dev, data, fops); + if (inode) { + d_instantiate(dentry, inode); + dget(dentry); +@@ -84,12 +91,13 @@ static int debugfs_mknod(struct inode *d + return error; + } + +-static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + int res; + + mode = (mode & (S_IRWXUGO | S_ISVTX)) | S_IFDIR; +- res = debugfs_mknod(dir, dentry, mode, 0); ++ res = debugfs_mknod(dir, dentry, mode, 0, data, fops); + if (!res) { + inc_nlink(dir); + fsnotify_mkdir(dir, dentry); +@@ -97,18 +105,20 @@ static int debugfs_mkdir(struct inode *d + return res; + } + +-static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + mode = (mode & S_IALLUGO) | S_IFLNK; +- return debugfs_mknod(dir, dentry, mode, 0); ++ return debugfs_mknod(dir, dentry, mode, 0, data, fops); + } + +-static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) ++static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode, ++ void *data, const struct file_operations *fops) + { + int res; + + mode = (mode & S_IALLUGO) | S_IFREG; +- res = debugfs_mknod(dir, dentry, mode, 0); ++ res = debugfs_mknod(dir, dentry, mode, 0, data, fops); + if (!res) + fsnotify_create(dir, dentry); + return res; +@@ -142,7 +152,9 @@ static struct file_system_type debug_fs_ + + static int debugfs_create_by_name(const char *name, mode_t mode, + struct dentry *parent, +- struct dentry **dentry) ++ struct dentry **dentry, ++ void *data, ++ const struct file_operations *fops) + { + int error = 0; + +@@ -167,13 +179,16 @@ static int debugfs_create_by_name(const + if (!IS_ERR(*dentry)) { + switch (mode & S_IFMT) { + case S_IFDIR: +- error = debugfs_mkdir(parent->d_inode, *dentry, mode); ++ error = debugfs_mkdir(parent->d_inode, *dentry, mode, ++ data, fops); + break; + case S_IFLNK: +- error = debugfs_link(parent->d_inode, *dentry, mode); ++ error = debugfs_link(parent->d_inode, *dentry, mode, ++ data, fops); + break; + default: +- error = debugfs_create(parent->d_inode, *dentry, mode); ++ error = debugfs_create(parent->d_inode, *dentry, mode, ++ data, fops); + break; + } + dput(*dentry); +@@ -224,19 +239,13 @@ struct dentry *debugfs_create_file(const + if (error) + goto exit; + +- error = debugfs_create_by_name(name, mode, parent, &dentry); ++ error = debugfs_create_by_name(name, mode, parent, &dentry, ++ data, fops); + if (error) { + dentry = NULL; + simple_release_fs(&debugfs_mount, &debugfs_mount_count); + goto exit; + } +- +- if (dentry->d_inode) { +- if (data) +- dentry->d_inode->i_private = data; +- if (fops) +- dentry->d_inode->i_fop = fops; +- } + exit: + return dentry; + } diff --git a/queue-2.6.27/firewire-ohci-handle-receive-packets-with-a-data-length-of-zero.patch b/queue-2.6.27/firewire-ohci-handle-receive-packets-with-a-data-length-of-zero.patch new file mode 100644 index 00000000000..62a3a392457 --- /dev/null +++ b/queue-2.6.27/firewire-ohci-handle-receive-packets-with-a-data-length-of-zero.patch @@ -0,0 +1,59 @@ +From 8c0c0cc2d9f4c523fde04bdfe41e4380dec8ee54 Mon Sep 17 00:00:00 2001 +From: Jay Fenlason +Date: Fri, 11 Dec 2009 14:23:58 -0500 +Subject: firewire: ohci: handle receive packets with a data length of zero + +From: Jay Fenlason + +commit 8c0c0cc2d9f4c523fde04bdfe41e4380dec8ee54 upstream. + +Queueing to receive an ISO packet with a payload length of zero +silently does nothing in dualbuffer mode, and crashes the kernel in +packet-per-buffer mode. Return an error in dualbuffer mode, because +the DMA controller won't let us do what we want, and work correctly in +packet-per-buffer mode. + +Signed-off-by: Jay Fenlason +Signed-off-by: Stefan Richter +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firewire/fw-ohci.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/drivers/firewire/fw-ohci.c ++++ b/drivers/firewire/fw-ohci.c +@@ -2146,6 +2146,13 @@ ohci_queue_iso_receive_dualbuffer(struct + page = payload >> PAGE_SHIFT; + offset = payload & ~PAGE_MASK; + rest = p->payload_length; ++ /* ++ * The controllers I've tested have not worked correctly when ++ * second_req_count is zero. Rather than do something we know won't ++ * work, return an error ++ */ ++ if (rest == 0) ++ return -EINVAL; + + /* FIXME: make packet-per-buffer/dual-buffer a context option */ + while (rest > 0) { +@@ -2199,7 +2206,7 @@ ohci_queue_iso_receive_packet_per_buffer + unsigned long payload) + { + struct iso_context *ctx = container_of(base, struct iso_context, base); +- struct descriptor *d = NULL, *pd = NULL; ++ struct descriptor *d, *pd; + struct fw_iso_packet *p = packet; + dma_addr_t d_bus, page_bus; + u32 z, header_z, rest; +@@ -2237,8 +2244,9 @@ ohci_queue_iso_receive_packet_per_buffer + d->data_address = cpu_to_le32(d_bus + (z * sizeof(*d))); + + rest = payload_per_buffer; ++ pd = d; + for (j = 1; j < z; j++) { +- pd = d + j; ++ pd++; + pd->control = cpu_to_le16(DESCRIPTOR_STATUS | + DESCRIPTOR_INPUT_MORE); + diff --git a/queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch b/queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch new file mode 100644 index 00000000000..93c773271df --- /dev/null +++ b/queue-2.6.27/fuse-reject-o_direct-flag-also-in-fuse_create.patch @@ -0,0 +1,43 @@ +From 1b7323965a8c6eee9dc4e345a7ae4bff1dc93149 Mon Sep 17 00:00:00 2001 +From: Csaba Henk +Date: Fri, 27 Nov 2009 19:30:14 +0530 +Subject: fuse: reject O_DIRECT flag also in fuse_create + +From: Csaba Henk + +commit 1b7323965a8c6eee9dc4e345a7ae4bff1dc93149 upstream. + +The comment in fuse_open about O_DIRECT: + + "VFS checks this, but only _after_ ->open()" + +also holds for fuse_create, however, the same kind of check was missing there. + +As an impact of this bug, open(newfile, O_RDWR|O_CREAT|O_DIRECT) fails, but a +stub newfile will remain if the fuse server handled the implied FUSE_CREATE +request appropriately. + +Other impact: in the above situation ima_file_free() will complain to open/free +imbalance if CONFIG_IMA is set. + +Signed-off-by: Csaba Henk +Signed-off-by: Miklos Szeredi +Cc: Harshavardhana +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -401,6 +401,9 @@ static int fuse_create_open(struct inode + if (flags & O_DIRECT) + return -EINVAL; + ++ if (flags & O_DIRECT) ++ return -EINVAL; ++ + forget_req = fuse_get_req(fc); + if (IS_ERR(forget_req)) + return PTR_ERR(forget_req); diff --git a/queue-2.6.27/hfs-fix-a-potential-buffer-overflow.patch b/queue-2.6.27/hfs-fix-a-potential-buffer-overflow.patch new file mode 100644 index 00000000000..1a1d9a15695 --- /dev/null +++ b/queue-2.6.27/hfs-fix-a-potential-buffer-overflow.patch @@ -0,0 +1,95 @@ +From ec81aecb29668ad71f699f4e7b96ec46691895b6 Mon Sep 17 00:00:00 2001 +From: Amerigo Wang +Date: Mon, 14 Dec 2009 17:57:37 -0800 +Subject: hfs: fix a potential buffer overflow + +From: Amerigo Wang + +commit ec81aecb29668ad71f699f4e7b96ec46691895b6 upstream. + +A specially-crafted Hierarchical File System (HFS) filesystem could cause +a buffer overflow to occur in a process's kernel stack during a memcpy() +call within the hfs_bnode_read() function (at fs/hfs/bnode.c:24). The +attacker can provide the source buffer and length, and the destination +buffer is a local variable of a fixed length. This local variable (passed +as "&entry" from fs/hfs/dir.c:112 and allocated on line 60) is stored in +the stack frame of hfs_bnode_read()'s caller, which is hfs_readdir(). +Because the hfs_readdir() function executes upon any attempt to read a +directory on the filesystem, it gets called whenever a user attempts to +inspect any filesystem contents. + +[amwang@redhat.com: modify this patch and fix coding style problems] +Signed-off-by: WANG Cong +Cc: Eugene Teo +Cc: Roman Zippel +Cc: Al Viro +Cc: Christoph Hellwig +Cc: Alexey Dobriyan +Cc: Dave Anderson +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/hfs/catalog.c | 4 ++++ + fs/hfs/dir.c | 11 +++++++++++ + fs/hfs/super.c | 7 ++++++- + 3 files changed, 21 insertions(+), 1 deletion(-) + +--- a/fs/hfs/catalog.c ++++ b/fs/hfs/catalog.c +@@ -289,6 +289,10 @@ int hfs_cat_move(u32 cnid, struct inode + err = hfs_brec_find(&src_fd); + if (err) + goto out; ++ if (src_fd.entrylength > sizeof(entry) || src_fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } + + hfs_bnode_read(src_fd.bnode, &entry, src_fd.entryoffset, + src_fd.entrylength); +--- a/fs/hfs/dir.c ++++ b/fs/hfs/dir.c +@@ -79,6 +79,11 @@ static int hfs_readdir(struct file *filp + filp->f_pos++; + /* fall through */ + case 1: ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + if (entry.type != HFS_CDR_THD) { + printk(KERN_ERR "hfs: bad catalog folder thread\n"); +@@ -109,6 +114,12 @@ static int hfs_readdir(struct file *filp + err = -EIO; + goto out; + } ++ ++ if (fd.entrylength > sizeof(entry) || fd.entrylength < 0) { ++ err = -EIO; ++ goto out; ++ } ++ + hfs_bnode_read(fd.bnode, &entry, fd.entryoffset, fd.entrylength); + type = entry.type; + len = hfs_mac2asc(sb, strbuf, &fd.key->cat.CName); +--- a/fs/hfs/super.c ++++ b/fs/hfs/super.c +@@ -386,8 +386,13 @@ static int hfs_fill_super(struct super_b + /* try to get the root inode */ + hfs_find_init(HFS_SB(sb)->cat_tree, &fd); + res = hfs_cat_find_brec(sb, HFS_ROOT_CNID, &fd); +- if (!res) ++ if (!res) { ++ if (fd.entrylength > sizeof(rec) || fd.entrylength < 0) { ++ res = -EIO; ++ goto bail; ++ } + hfs_bnode_read(fd.bnode, &rec, fd.entryoffset, fd.entrylength); ++ } + if (res) { + hfs_find_exit(&fd); + goto bail_no_root; diff --git a/queue-2.6.27/pata_hpt-37x-3x2n-fix-timing-register-masks-take-2.patch b/queue-2.6.27/pata_hpt-37x-3x2n-fix-timing-register-masks-take-2.patch new file mode 100644 index 00000000000..51cb8f5b78f --- /dev/null +++ b/queue-2.6.27/pata_hpt-37x-3x2n-fix-timing-register-masks-take-2.patch @@ -0,0 +1,173 @@ +From 5600c70e576199a7552e1c0fff43f3fe16f5566e Mon Sep 17 00:00:00 2001 +From: Sergei Shtylyov +Date: Fri, 27 Nov 2009 22:29:02 +0400 +Subject: pata_hpt{37x|3x2n}: fix timing register masks (take 2) + +From: Sergei Shtylyov + +commit 5600c70e576199a7552e1c0fff43f3fe16f5566e upstream. + +These drivers inherited from the older 'hpt366' IDE driver the buggy timing +register masks in their set_piomode() metods. As a result, too low command +cycle active time is programmed for slow PIO modes. Quite fortunately, it's +later "fixed up" by the set_dmamode() methods which also "helpfully" reprogram +the command timings, usually to PIO mode 4; unfortunately, setting an UltraDMA +mode #N also reprograms already set PIO data timings, usually to MWDMA mode # +max(N, 2) timings... + +However, the drivers added some breakage of their own too: the bit that they +set/clear to control the FIFO is sometimes wrong -- it's actually the MSB of +the command cycle setup time; also, setting it in DMA mode is wrong as this +bit is only for PIO actually and clearing it for PIO modes is not needed as +no mode in any timing table has it set... + +Fix all this, inverting the masks while at it, like in the 'hpt366' and +'pata_hpt366' drivers; bump the drivers' versions, accounting for recent +patches that forgot to do it... + +Signed-off-by: Sergei Shtylyov +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/pata_hpt37x.c | 32 +++++++++++++++----------------- + drivers/ata/pata_hpt3x2n.c | 17 ++++++++--------- + 2 files changed, 23 insertions(+), 26 deletions(-) + +--- a/drivers/ata/pata_hpt37x.c ++++ b/drivers/ata/pata_hpt37x.c +@@ -24,7 +24,7 @@ + #include + + #define DRV_NAME "pata_hpt37x" +-#define DRV_VERSION "0.6.12" ++#define DRV_VERSION "0.6.14" + + struct hpt_clock { + u8 xfer_speed; +@@ -404,9 +404,8 @@ static void hpt370_set_piomode(struct at + + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->pio_mode); +- mode &= ~0x8000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -423,8 +422,7 @@ static void hpt370_set_dmamode(struct at + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -436,11 +434,12 @@ static void hpt370_set_dmamode(struct at + fast |= 0x01; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->dma_mode); +- mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ +- mode &= ~0xC0000000; /* Leave config bits alone */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -508,9 +507,8 @@ static void hpt372_set_piomode(struct at + mode = hpt37x_find_mode(ap, adev->pio_mode); + + printk("Find mode for %d reports %X\n", adev->pio_mode, mode); +- mode &= ~0x80000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -527,8 +525,7 @@ static void hpt372_set_dmamode(struct at + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -539,12 +536,13 @@ static void hpt372_set_dmamode(struct at + fast &= ~0x07; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt37x_find_mode(ap, adev->dma_mode); + printk("Find mode for DMA %d reports %X\n", adev->dma_mode, mode); +- mode &= ~0xC0000000; /* Leave config bits alone */ +- mode |= 0x80000000; /* FIFO in MWDMA or UDMA */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + +--- a/drivers/ata/pata_hpt3x2n.c ++++ b/drivers/ata/pata_hpt3x2n.c +@@ -25,7 +25,7 @@ + #include + + #define DRV_NAME "pata_hpt3x2n" +-#define DRV_VERSION "0.3.4" ++#define DRV_VERSION "0.3.7" + + enum { + HPT_PCI_FAST = (1 << 31), +@@ -185,9 +185,8 @@ static void hpt3x2n_set_piomode(struct a + + pci_read_config_dword(pdev, addr1, ®); + mode = hpt3x2n_find_mode(ap, adev->pio_mode); +- mode &= ~0x8000000; /* No FIFO in PIO */ +- mode &= ~0x30070000; /* Leave config bits alone */ +- reg &= 0x30070000; /* Strip timing bits */ ++ mode &= 0xCFC3FFFF; /* Leave DMA bits alone */ ++ reg &= ~0xCFC3FFFF; /* Strip timing bits */ + pci_write_config_dword(pdev, addr1, reg | mode); + } + +@@ -204,8 +203,7 @@ static void hpt3x2n_set_dmamode(struct a + { + struct pci_dev *pdev = to_pci_dev(ap->host->dev); + u32 addr1, addr2; +- u32 reg; +- u32 mode; ++ u32 reg, mode, mask; + u8 fast; + + addr1 = 0x40 + 4 * (adev->devno + 2 * ap->port_no); +@@ -216,11 +214,12 @@ static void hpt3x2n_set_dmamode(struct a + fast &= ~0x07; + pci_write_config_byte(pdev, addr2, fast); + ++ mask = adev->dma_mode < XFER_UDMA_0 ? 0x31C001FF : 0x303C0000; ++ + pci_read_config_dword(pdev, addr1, ®); + mode = hpt3x2n_find_mode(ap, adev->dma_mode); +- mode |= 0x8000000; /* FIFO in MWDMA or UDMA */ +- mode &= ~0xC0000000; /* Leave config bits alone */ +- reg &= 0xC0000000; /* Strip timing bits */ ++ mode &= mask; ++ reg &= ~mask; + pci_write_config_dword(pdev, addr1, reg | mode); + } + diff --git a/queue-2.6.27/series b/queue-2.6.27/series index 0b37ab67df4..2f06465f62d 100644 --- a/queue-2.6.27/series +++ b/queue-2.6.27/series @@ -1 +1,13 @@ signal-fix-alternate-signal-stack-check.patch +debugfs-fix-create-mutex-racy-fops-and-private-data.patch +firewire-ohci-handle-receive-packets-with-a-data-length-of-zero.patch +fuse-reject-o_direct-flag-also-in-fuse_create.patch +hfs-fix-a-potential-buffer-overflow.patch +pata_hpt-37x-3x2n-fix-timing-register-masks-take-2.patch +ssb-fix-range-check-in-sprom-write.patch +v4l-dvb-fix-test-in-copy_reg_bits.patch +x86-apic-enable-lapic-nmi-watchdog-on-amd-family-11h.patch +x86-asus-p4s800-reboot-bios-quirk.patch +x86-calgary-iommu-quirk-find-nearest-matching-calgary-while-walking-up-the-pci-tree.patch +x86-fix-iommu-nodac-parameter-handling.patch +x86-gart-pci-gart_64.c-use-correct-length-in-strncmp.patch diff --git a/queue-2.6.27/ssb-fix-range-check-in-sprom-write.patch b/queue-2.6.27/ssb-fix-range-check-in-sprom-write.patch new file mode 100644 index 00000000000..e0fe1fd8c8b --- /dev/null +++ b/queue-2.6.27/ssb-fix-range-check-in-sprom-write.patch @@ -0,0 +1,66 @@ +From e33761e6f23881de9f3ee77cc2204ab2e26f3d9a Mon Sep 17 00:00:00 2001 +From: Michael Buesch +Date: Mon, 23 Nov 2009 20:58:06 +0100 +Subject: ssb: Fix range check in sprom write + +From: Michael Buesch + +commit e33761e6f23881de9f3ee77cc2204ab2e26f3d9a upstream. + +The range check in the sprom image parser hex2sprom() is broken. +One sprom word is 4 hex characters. +This fixes the check and also adds much better sanity checks to the code. +We better make sure the image is OK by doing some sanity checks to avoid +bricking the device by accident. + +Signed-off-by: Michael Buesch +Signed-off-by: John W. Linville +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ssb/sprom.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +--- a/drivers/ssb/sprom.c ++++ b/drivers/ssb/sprom.c +@@ -13,6 +13,8 @@ + + #include "ssb_private.h" + ++#include ++ + + static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len, + size_t sprom_size_words) +@@ -30,17 +32,27 @@ static int sprom2hex(const u16 *sprom, c + static int hex2sprom(u16 *sprom, const char *dump, size_t len, + size_t sprom_size_words) + { +- char tmp[5] = { 0 }; +- int cnt = 0; ++ char c, tmp[5] = { 0 }; ++ int err, cnt = 0; + unsigned long parsed; + +- if (len < sprom_size_words * 2) ++ /* Strip whitespace at the end. */ ++ while (len) { ++ c = dump[len - 1]; ++ if (!isspace(c) && c != '\0') ++ break; ++ len--; ++ } ++ /* Length must match exactly. */ ++ if (len != sprom_size_words * 4) + return -EINVAL; + + while (cnt < sprom_size_words) { + memcpy(tmp, dump, 4); + dump += 4; +- parsed = simple_strtoul(tmp, NULL, 16); ++ err = strict_strtoul(tmp, 16, &parsed); ++ if (err) ++ return err; + sprom[cnt++] = swab16((u16)parsed); + } + diff --git a/queue-2.6.27/v4l-dvb-fix-test-in-copy_reg_bits.patch b/queue-2.6.27/v4l-dvb-fix-test-in-copy_reg_bits.patch new file mode 100644 index 00000000000..da54bc390cf --- /dev/null +++ b/queue-2.6.27/v4l-dvb-fix-test-in-copy_reg_bits.patch @@ -0,0 +1,32 @@ +From c95a419a5604ec8a23cd73f61e9bb151e8cbe89b Mon Sep 17 00:00:00 2001 +From: Roel Kluin +Date: Fri, 20 Nov 2009 15:34:13 -0300 +Subject: V4L/DVB: Fix test in copy_reg_bits() + +From: Roel Kluin + +commit c95a419a5604ec8a23cd73f61e9bb151e8cbe89b upstream. + +The reg_pair2[j].reg was tested twice. + +Signed-off-by: Roel Kluin +Acked-by: Michael Krufky +Signed-off-by: Andrew Morton +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/common/tuners/mxl5007t.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/media/common/tuners/mxl5007t.c ++++ b/drivers/media/common/tuners/mxl5007t.c +@@ -207,7 +207,7 @@ static void copy_reg_bits(struct reg_pai + i = j = 0; + + while (reg_pair1[i].reg || reg_pair1[i].val) { +- while (reg_pair2[j].reg || reg_pair2[j].reg) { ++ while (reg_pair2[j].reg || reg_pair2[j].val) { + if (reg_pair1[i].reg != reg_pair2[j].reg) { + j++; + continue; diff --git a/queue-2.6.27/x86-apic-enable-lapic-nmi-watchdog-on-amd-family-11h.patch b/queue-2.6.27/x86-apic-enable-lapic-nmi-watchdog-on-amd-family-11h.patch new file mode 100644 index 00000000000..42d72a01f31 --- /dev/null +++ b/queue-2.6.27/x86-apic-enable-lapic-nmi-watchdog-on-amd-family-11h.patch @@ -0,0 +1,47 @@ +From 7d1849aff6687a135a8da3a75e32a00e3137a5e2 Mon Sep 17 00:00:00 2001 +From: Mikael Pettersson +Date: Thu, 3 Dec 2009 15:52:44 +0100 +Subject: x86, apic: Enable lapic nmi watchdog on AMD Family 11h + +From: Mikael Pettersson + +commit 7d1849aff6687a135a8da3a75e32a00e3137a5e2 upstream. + +The x86 lapic nmi watchdog does not recognize AMD Family 11h, +resulting in: + + NMI watchdog: CPU not supported + +As far as I can see from available documentation (the BKDM), +family 11h looks identical to family 10h as far as the PMU +is concerned. + +Extending the check to accept family 11h results in: + + Testing NMI watchdog ... OK. + +I've been running with this change on a Turion X2 Ultra ZM-82 +laptop for a couple of weeks now without problems. + +Signed-off-by: Mikael Pettersson +Cc: Andreas Herrmann +Cc: Joerg Roedel +LKML-Reference: <19223.53436.931768.278021@pilspetsen.it.uu.se> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/cpu/perfctr-watchdog.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/perfctr-watchdog.c ++++ b/arch/x86/kernel/cpu/perfctr-watchdog.c +@@ -646,7 +646,7 @@ static void probe_nmi_watchdog(void) + switch (boot_cpu_data.x86_vendor) { + case X86_VENDOR_AMD: + if (boot_cpu_data.x86 != 6 && boot_cpu_data.x86 != 15 && +- boot_cpu_data.x86 != 16) ++ boot_cpu_data.x86 != 16 && boot_cpu_data.x86 != 17) + return; + wd_ops = &k7_wd_ops; + break; diff --git a/queue-2.6.27/x86-asus-p4s800-reboot-bios-quirk.patch b/queue-2.6.27/x86-asus-p4s800-reboot-bios-quirk.patch new file mode 100644 index 00000000000..eca0355adc9 --- /dev/null +++ b/queue-2.6.27/x86-asus-p4s800-reboot-bios-quirk.patch @@ -0,0 +1,63 @@ +From 4832ddda2ec4df96ea1eed334ae2dbd65fc1f541 Mon Sep 17 00:00:00 2001 +From: Leann Ogasawara +Date: Fri, 4 Dec 2009 15:42:22 -0800 +Subject: x86: ASUS P4S800 reboot=bios quirk + +From: Leann Ogasawara + +commit 4832ddda2ec4df96ea1eed334ae2dbd65fc1f541 upstream. + +Bug reporter noted their system with an ASUS P4S800 motherboard would +hang when rebooting unless reboot=b was specified. Their dmidecode +didn't contain descriptive System Information for Manufacturer or +Product Name, so I used their Base Board Information to create a +reboot quirk patch. The bug reporter confirmed this patch resolves +the reboot hang. + +Handle 0x0001, DMI type 1, 25 bytes +System Information + Manufacturer: System Manufacturer + Product Name: System Name + Version: System Version + Serial Number: SYS-1234567890 + UUID: E0BFCD8B-7948-D911-A953-E486B4EEB67F + Wake-up Type: Power Switch + +Handle 0x0002, DMI type 2, 8 bytes +Base Board Information + Manufacturer: ASUSTeK Computer INC. + Product Name: P4S800 + Version: REV 1.xx + Serial Number: xxxxxxxxxxx + +BugLink: http://bugs.launchpad.net/bugs/366682 + +ASUS P4S800 will hang when rebooting unless reboot=b is specified. +Add a quirk to reboot through the bios. + +Signed-off-by: Leann Ogasawara +LKML-Reference: <1259972107.4629.275.camel@emiko> +Signed-off-by: H. Peter Anvin +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/reboot.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -219,6 +219,14 @@ static struct dmi_system_id __initdata r + DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), + }, + }, ++ { /* Handle problems with rebooting on ASUS P4S800 */ ++ .callback = set_bios_reboot, ++ .ident = "ASUS P4S800", ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), ++ DMI_MATCH(DMI_BOARD_NAME, "P4S800"), ++ }, ++ }, + { } + }; + diff --git a/queue-2.6.27/x86-calgary-iommu-quirk-find-nearest-matching-calgary-while-walking-up-the-pci-tree.patch b/queue-2.6.27/x86-calgary-iommu-quirk-find-nearest-matching-calgary-while-walking-up-the-pci-tree.patch new file mode 100644 index 00000000000..610dc50243d --- /dev/null +++ b/queue-2.6.27/x86-calgary-iommu-quirk-find-nearest-matching-calgary-while-walking-up-the-pci-tree.patch @@ -0,0 +1,83 @@ +From 4528752f49c1f4025473d12bc5fa9181085c3f22 Mon Sep 17 00:00:00 2001 +From: Darrick J. Wong +Date: Wed, 2 Dec 2009 15:05:56 -0800 +Subject: x86, Calgary IOMMU quirk: Find nearest matching Calgary while walking up the PCI tree + +From: Darrick J. Wong + +commit 4528752f49c1f4025473d12bc5fa9181085c3f22 upstream. + +On a multi-node x3950M2 system, there's a slight oddity in the +PCI device tree for all secondary nodes: + + 30:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev e1) + \-33:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) + \-34:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 1078 (rev 04) + +...as compared to the primary node: + + 00:1e.0 PCI bridge: Intel Corporation 82801 PCI Bridge (rev e1) + \-01:00.0 VGA compatible controller: ATI Technologies Inc ES1000 (rev 02) + 03:00.0 PCI bridge: IBM CalIOC2 PCI-E Root Port (rev 01) + \-04:00.0 RAID bus controller: LSI Logic / Symbios Logic MegaRAID SAS 1078 (rev 04) + +In both nodes, the LSI RAID controller hangs off a CalIOC2 +device, but on the secondary nodes, the BIOS hides the VGA +device and substitutes the device tree ending with the disk +controller. + +It would seem that Calgary devices don't necessarily appear at +the top of the PCI tree, which means that the current code to +find the Calgary IOMMU that goes with a particular device is +buggy. + +Rather than walk all the way to the top of the PCI +device tree and try to match bus number with Calgary descriptor, +the code needs to examine each parent of the particular device; +if it encounters a Calgary with a matching bus number, simply +use that. + +Otherwise, we BUG() when the bus number of the Calgary doesn't +match the bus number of whatever's at the top of the device tree. + +Extra note: This patch appears to work correctly for the x3950 +that came before the x3950 M2. + +Signed-off-by: Darrick J. Wong +Acked-by: Muli Ben-Yehuda +Cc: FUJITA Tomonori +Cc: Joerg Roedel +Cc: Yinghai Lu +Cc: Jon D. Mason +Cc: Corinna Schultz +LKML-Reference: <20091202230556.GG10295@tux1.beaverton.ibm.com> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/pci-calgary_64.c | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) + +--- a/arch/x86/kernel/pci-calgary_64.c ++++ b/arch/x86/kernel/pci-calgary_64.c +@@ -377,13 +377,15 @@ static inline struct iommu_table *find_i + + pdev = to_pci_dev(dev); + ++ /* search up the device tree for an iommu */ + pbus = pdev->bus; +- +- /* is the device behind a bridge? Look for the root bus */ +- while (pbus->parent) ++ do { ++ tbl = pci_iommu(pbus); ++ if (tbl && tbl->it_busno == pbus->number) ++ break; ++ tbl = NULL; + pbus = pbus->parent; +- +- tbl = pci_iommu(pbus); ++ } while (pbus); + + BUG_ON(tbl && (tbl->it_busno != pbus->number)); + diff --git a/queue-2.6.27/x86-fix-iommu-nodac-parameter-handling.patch b/queue-2.6.27/x86-fix-iommu-nodac-parameter-handling.patch new file mode 100644 index 00000000000..c7369513281 --- /dev/null +++ b/queue-2.6.27/x86-fix-iommu-nodac-parameter-handling.patch @@ -0,0 +1,33 @@ +From 2ae8bb75db1f3de422eb5898f2a063c46c36dba8 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Mon, 26 Oct 2009 15:41:46 +0100 +Subject: x86: Fix iommu=nodac parameter handling + +From: Tejun Heo + +commit 2ae8bb75db1f3de422eb5898f2a063c46c36dba8 upstream. + +iommu=nodac should forbid dac instead of enabling it. Fix it. + +Signed-off-by: Tejun Heo +Acked-by: FUJITA Tomonori +Cc: Matteo Frigo +LKML-Reference: <4AE5B52A.4050408@kernel.org> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/pci-dma.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/pci-dma.c ++++ b/arch/x86/kernel/pci-dma.c +@@ -175,7 +175,7 @@ static __init int iommu_setup(char *p) + if (!strncmp(p, "allowdac", 8)) + forbid_dac = 0; + if (!strncmp(p, "nodac", 5)) +- forbid_dac = -1; ++ forbid_dac = 1; + if (!strncmp(p, "usedac", 6)) { + forbid_dac = -1; + return 1; diff --git a/queue-2.6.27/x86-gart-pci-gart_64.c-use-correct-length-in-strncmp.patch b/queue-2.6.27/x86-gart-pci-gart_64.c-use-correct-length-in-strncmp.patch new file mode 100644 index 00000000000..28015e2f3b0 --- /dev/null +++ b/queue-2.6.27/x86-gart-pci-gart_64.c-use-correct-length-in-strncmp.patch @@ -0,0 +1,29 @@ +From 41855b77547fa18d90ed6a5d322983d3fdab1959 Mon Sep 17 00:00:00 2001 +From: Joe Perches +Date: Mon, 9 Nov 2009 17:58:50 -0800 +Subject: x86: GART: pci-gart_64.c: Use correct length in strncmp + +From: Joe Perches + +commit 41855b77547fa18d90ed6a5d322983d3fdab1959 upstream. + +Signed-off-by: Joe Perches +LKML-Reference: <1257818330.12852.72.camel@Joe-Laptop.home> +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/pci-gart_64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/x86/kernel/pci-gart_64.c ++++ b/arch/x86/kernel/pci-gart_64.c +@@ -865,7 +865,7 @@ void __init gart_parse_options(char *p) + #endif + if (isdigit(*p) && get_option(&p, &arg)) + iommu_size = arg; +- if (!strncmp(p, "fullflush", 8)) ++ if (!strncmp(p, "fullflush", 9)) + iommu_fullflush = 1; + if (!strncmp(p, "nofullflush", 11)) + iommu_fullflush = 0; -- 2.47.3