From 98acfc7e8e2606fadae6d2bf99fa040be917ce8c Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Wed, 1 Mar 2006 12:04:46 -0700 Subject: [PATCH 01/47] [SCSI] Add Brownie to blacklist This device spews total rubbish to a REPORT LUNS command, so avoid sending it one. Signed-off-by: Matthew Wilcox Signed-off-by: James Bottomley --- drivers/scsi/scsi_devinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index f01ec0a7c506..84c3937ae8fb 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -126,6 +126,7 @@ static struct { {"ADAPTEC", "Adaptec 5400S", NULL, BLIST_FORCELUN}, {"AFT PRO", "-IX CF", "0.0>", BLIST_FORCELUN}, {"BELKIN", "USB 2 HS-CF", "1.95", BLIST_FORCELUN | BLIST_INQUIRY_36}, + {"BROWNIE", "1600U3P", NULL, BLIST_NOREPORTLUN}, {"CANON", "IPUBJD", NULL, BLIST_SPARSELUN}, {"CBOX3", "USB Storage-SMC", "300A", BLIST_FORCELUN | BLIST_INQUIRY_36}, {"CMD", "CRA-7280", NULL, BLIST_SPARSELUN}, /* CMD RAID Controller */ From 35dc2585fa32a2b300307ffa9f17122b13ccef97 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 2 Mar 2006 21:28:54 +0100 Subject: [PATCH 02/47] [SCSI] zfcp: correctly set this_id for hosts It fixes a bug in zfcp which provokes a race in scsi_scan.c. Finally this can lead to an Oops like: kernel BUG at fs/sysfs/symlink.c:87! Correctly set this_id for the host. Otherwise we provoke a race between scsi_target_reap_work and concurrent scsi_add_device. Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 9f6b4d7a46f3..a2de3c9afe49 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -68,7 +68,7 @@ struct zfcp_data zfcp_data = { eh_host_reset_handler: zfcp_scsi_eh_host_reset_handler, /* FIXME(openfcp): Tune */ can_queue: 4096, - this_id: 0, + this_id: -1, /* * FIXME: * one less? can zfcp_create_sbale cope with it? From cdaeedae9844ec3deaafa00b7dd8c21e01368633 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Sun, 5 Mar 2006 11:42:06 +0100 Subject: [PATCH 03/47] [SCSI] scsi: aha152x pcmcia driver needs spi transport AHA152X PCMCIA module needs spi_print_msg. Signed-off-by: Dominik Brodowski Signed-off-by: James Bottomley --- drivers/scsi/pcmcia/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/scsi/pcmcia/Kconfig b/drivers/scsi/pcmcia/Kconfig index df52190f4d94..eac8e179cfff 100644 --- a/drivers/scsi/pcmcia/Kconfig +++ b/drivers/scsi/pcmcia/Kconfig @@ -8,6 +8,7 @@ menu "PCMCIA SCSI adapter support" config PCMCIA_AHA152X tristate "Adaptec AHA152X PCMCIA support" depends on m && !64BIT + select SCSI_SPI_ATTRS help Say Y here if you intend to attach this type of PCMCIA SCSI host adapter to your computer. From 3c8fdae78cf5d73c6739912a1ff087c0f23b2a47 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 8 Mar 2006 17:25:33 +0000 Subject: [PATCH 04/47] [ARM] Fix muldi3.S When shifting the low-parts of signed numbers, a logical shift should be used to avoid sign-extending a bit which isn't a sign bit. Signed-off-by: Russell King --- arch/arm/lib/muldi3.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/lib/muldi3.S b/arch/arm/lib/muldi3.S index 72d594184b8a..d89c60615794 100644 --- a/arch/arm/lib/muldi3.S +++ b/arch/arm/lib/muldi3.S @@ -29,8 +29,8 @@ ENTRY(__aeabi_lmul) mul xh, yl, xh mla xh, xl, yh, xh - mov ip, xl, asr #16 - mov yh, yl, asr #16 + mov ip, xl, lsr #16 + mov yh, yl, lsr #16 bic xl, xl, ip, lsl #16 bic yl, yl, yh, lsl #16 mla xh, yh, ip, xh From dcc8fa50ebc251a1394a2c8561eee7d79cc5f437 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Wed, 8 Mar 2006 23:45:10 +0000 Subject: [PATCH 05/47] [ARM] 3354/1: NAS100d: fix power led handling Patch from Alessandro Zummo Disable GPIO clocks to allow the power led to work properly. Signed-off-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/nas100d-setup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 856d56f3b2ae..a3b4c6ac5708 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -113,6 +113,9 @@ static void __init nas100d_init(void) { ixp4xx_sys_init(); + /* gpio 14 and 15 are _not_ clocks */ + *IXP4XX_GPIO_GPCLKR = 0; + nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0); nas100d_flash_resource.end = IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1; From e7fcdb79ecaa01e2eba06e3fb64e10455bdb5aa7 Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Wed, 8 Mar 2006 23:45:12 +0000 Subject: [PATCH 06/47] [ARM] 3355/1: NSLU2: remove propmt depends Patch from Alessandro Zummo The patch that would have made the NSLU2 kernel non compatible with other ixp4xx machs never entered the kernel. So it is actually safe to remove the prompt dependencies. Signed-off-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/Kconfig | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index daadc78e271b..5bf50a2a737d 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -8,11 +8,9 @@ menu "Intel IXP4xx Implementation Options" comment "IXP4xx Platforms" -# This entry is placed on top because otherwise it would have -# been shown as a submenu. config MACH_NSLU2 bool - prompt "NSLU2" if !(MACH_IXDP465 || MACH_IXDPG425 || ARCH_IXDP425 || ARCH_ADI_COYOTE || ARCH_AVILA || ARCH_IXCDP1100 || ARCH_PRPMC1100 || MACH_GTWX5715) + prompt "Linksys NSLU2" help Say 'Y' here if you want your kernel to support Linksys's NSLU2 NAS device. For more information on this platform, From ad139a2f56e5789aa8a9f74e3600a7f854a38de9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 9 Mar 2006 16:37:49 +0100 Subject: [PATCH 07/47] [SCSI] scsi_transport_fc: fix FC_HOST_NUM_ATTRS In the past I added an host attribute but unfortunately I forgot to increase FC_HOST_NUM_ATTRS. This is fixed with the patch. Otherwise an fibre channel lld might run into BUG_ON(count > FC_HOST_NUM_ATTRS); in fc_attach_transport(). Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley --- drivers/scsi/scsi_transport_fc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 929032e370db..13ea64119b73 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -223,7 +223,7 @@ static void fc_rport_terminate(struct fc_rport *rport); */ #define FC_STARGET_NUM_ATTRS 3 #define FC_RPORT_NUM_ATTRS 9 -#define FC_HOST_NUM_ATTRS 16 +#define FC_HOST_NUM_ATTRS 17 struct fc_internal { struct scsi_transport_template t; From ad58f7dbeb6f5ea82679962f18985f16b660a2d9 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 10 Mar 2006 00:56:16 +0100 Subject: [PATCH 08/47] [SCSI] zfcp: fix device registration issues The patch fixes following issues: (1) Replace scsi_add_device with scsi_scan_target. (Thus the rport instead of the scsi_host becomes parent of a scsi_target again.) (2) Avoid scsi_device allocation during registration of an remote port. (Would be done during fc_scsi_scan_rport.) (3) Fix queuecommand behaviour when an zfcp unit is blocked. (Call scsi_done with DID_NO_CONNECT instead of returning SCSI_MLQUEUE_DEVICE_BUSY otherwise we might end up waiting for completion in blk_execute_rq for ever.) Signed-off-by: Andreas Herrmann Signed-off-by: James Bottomley --- drivers/s390/scsi/zfcp_def.h | 1 + drivers/s390/scsi/zfcp_erp.c | 11 +++++++---- drivers/s390/scsi/zfcp_scsi.c | 6 ++++-- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 7f551d66f47f..6eba56cd89ba 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h @@ -664,6 +664,7 @@ do { \ #define ZFCP_STATUS_UNIT_TEMPORARY 0x00000002 #define ZFCP_STATUS_UNIT_SHARED 0x00000004 #define ZFCP_STATUS_UNIT_READONLY 0x00000008 +#define ZFCP_STATUS_UNIT_REGISTERED 0x00000010 /* FSF request status (this does not have a common part) */ #define ZFCP_STATUS_FSFREQ_NOT_INIT 0x00000000 diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index e3c4bdd29a60..57cb628a05aa 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -3391,10 +3391,13 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, &unit->status)) && !unit->device - && port->rport) - scsi_add_device(port->adapter->scsi_host, 0, - port->rport->scsi_target_id, - unit->scsi_lun); + && port->rport) { + atomic_set_mask(ZFCP_STATUS_UNIT_REGISTERED, + &unit->status); + scsi_scan_target(&port->rport->dev, 0, + port->rport->scsi_target_id, + unit->scsi_lun, 0); + } zfcp_unit_put(unit); break; case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index a2de3c9afe49..9e6d07d7b3c8 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -183,7 +183,8 @@ zfcp_scsi_slave_alloc(struct scsi_device *sdp) read_lock_irqsave(&zfcp_data.config_lock, flags); unit = zfcp_unit_lookup(adapter, sdp->channel, sdp->id, sdp->lun); - if (unit) { + if (unit && atomic_test_mask(ZFCP_STATUS_UNIT_REGISTERED, + &unit->status)) { sdp->hostdata = unit; unit->device = sdp; zfcp_unit_get(unit); @@ -208,6 +209,7 @@ zfcp_scsi_slave_destroy(struct scsi_device *sdpnt) struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata; if (unit) { + atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status); sdpnt->hostdata = NULL; unit->device = NULL; zfcp_unit_put(unit); @@ -291,7 +293,7 @@ zfcp_scsi_command_async(struct zfcp_adapter *adapter, struct zfcp_unit *unit, "on port 0x%016Lx in recovery\n", zfcp_get_busid_by_unit(unit), unit->fcp_lun, unit->port->wwpn); - retval = SCSI_MLQUEUE_DEVICE_BUSY; + zfcp_scsi_command_fail(scpnt, DID_NO_CONNECT); goto out; } From 141fa40cff90881ac4d81f6afa27bc283fe7acca Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Fri, 10 Mar 2006 22:26:47 +0000 Subject: [PATCH 09/47] [ARM] 3356/1: Workaround for the ARM1136 I-cache invalidation problem Patch from Catalin Marinas ARM1136 erratum 371025 (category 2) specifies that, under rare conditions, an invalidate I-cache by MVA (line or range) operation can fail to invalidate a cache line. The recommended workaround is to either invalidate the entire I-cache or invalidate the range by set/way rather than MVA. Note that for a 16K cache size, invalidating a 4K page by set/way is equivalent to invalidating the entire I-cache. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/cache-v6.S | 7 ++++--- arch/arm/mm/flush.c | 6 ++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index d921c1024ae0..2c6c2a7c05a0 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S @@ -96,15 +96,16 @@ ENTRY(v6_coherent_user_range) #ifdef HARVARD_CACHE bic r0, r0, #CACHE_LINE_SIZE - 1 1: mcr p15, 0, r0, c7, c10, 1 @ clean D line - mcr p15, 0, r0, c7, c5, 1 @ invalidate I line add r0, r0, #CACHE_LINE_SIZE cmp r0, r1 blo 1b #endif - mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB -#ifdef HARVARD_CACHE mov r0, #0 +#ifdef HARVARD_CACHE mcr p15, 0, r0, c7, c10, 4 @ drain write buffer + mcr p15, 0, r0, c7, c5, 0 @ I+BTB cache invalidate +#else + mcr p15, 0, r0, c7, c5, 6 @ invalidate BTB #endif mov pc, lr diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 330695b6b19d..b103e56806bd 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -24,14 +24,16 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) { unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); + const int zero = 0; set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL)); flush_tlb_kernel_page(to); asm( "mcrr p15, 0, %1, %0, c14\n" - " mcrr p15, 0, %1, %0, c5\n" + " mcr p15, 0, %2, c7, c10, 4\n" + " mcr p15, 0, %2, c7, c5, 0\n" : - : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES) + : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) : "cc"); } From 04916c0ef482335cb0ae575dbc5a1d97619840cd Mon Sep 17 00:00:00 2001 From: Alessandro Zummo Date: Fri, 10 Mar 2006 22:30:01 +0000 Subject: [PATCH 10/47] [ARM] 3350/1: Enable 1-wire on ARM Patch from Alessandro Zummo This patches add the 1-wire drivers to the ARM Kconfig. Signed-off-by: Alessandro Zummo Signed-off-by: Russell King --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9f80fa502f8f..32ba00bd0a2f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -799,6 +799,8 @@ source "drivers/i2c/Kconfig" source "drivers/spi/Kconfig" +source "drivers/w1/Kconfig" + source "drivers/hwmon/Kconfig" #source "drivers/l3/Kconfig" From 6971ed1fbbc80cae54e082aae153d5b063885d0a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Mar 2006 12:47:54 +0900 Subject: [PATCH 11/47] [PATCH] ahci: fix NULL pointer dereference detected by Coverity Fix NULL pointer dereference detected by the Coverity checker. Kill dev -> pdev -> dev conversion while at it. Signed-off-by: Tejun Heo Cc: Adrian Bunk Signed-off-by: Jeff Garzik --- drivers/scsi/ahci.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index a800fb51168b..559ff7aae3f1 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -742,23 +742,17 @@ static irqreturn_t ahci_interrupt (int irq, void *dev_instance, struct pt_regs * struct ata_queued_cmd *qc; qc = ata_qc_from_tag(ap, ap->active_tag); if (!ahci_host_intr(ap, qc)) - if (ata_ratelimit()) { - struct pci_dev *pdev = - to_pci_dev(ap->host_set->dev); - dev_printk(KERN_WARNING, &pdev->dev, + if (ata_ratelimit()) + dev_printk(KERN_WARNING, host_set->dev, "unhandled interrupt on port %u\n", i); - } VPRINTK("port %u\n", i); } else { VPRINTK("port %u (no irq)\n", i); - if (ata_ratelimit()) { - struct pci_dev *pdev = - to_pci_dev(ap->host_set->dev); - dev_printk(KERN_WARNING, &pdev->dev, + if (ata_ratelimit()) + dev_printk(KERN_WARNING, host_set->dev, "interrupt on disabled port %u\n", i); - } } irq_ack |= (1 << i); From 8f22757ee84da64d4f662f1dd03dae95358a1efe Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Sat, 11 Mar 2006 18:49:13 -0800 Subject: [PATCH 12/47] [TUN]: Fix leak in tun_get_user() We're leaking an skb in a failure path in this function. Coverity #632 Signed-off-by: Dave Jones Signed-off-by: David S. Miller --- drivers/net/tun.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 50b8c6754b1e..a1ed2d983740 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -249,8 +249,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv, if (align) skb_reserve(skb, align); - if (memcpy_fromiovec(skb_put(skb, len), iv, len)) + if (memcpy_fromiovec(skb_put(skb, len), iv, len)) { + tun->stats.rx_dropped++; + kfree_skb(skb); return -EFAULT; + } skb->dev = tun->dev; switch (tun->flags & TUN_TYPE_MASK) { From 0ade309be739eceedc4812798da09d698a59867d Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sat, 11 Mar 2006 18:49:38 -0800 Subject: [PATCH 13/47] [TG3] tg3_bus_string(): remove dead code The Coverity checker spotted this dead code (note that (clock_ctrl == 7) is already handled above). Signed-off-by: Adrian Bunk Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 15545620ab0e..b8f1524da557 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -10543,8 +10543,6 @@ static char * __devinit tg3_bus_string(struct tg3 *tp, char *str) strcat(str, "66MHz"); else if (clock_ctrl == 6) strcat(str, "100MHz"); - else if (clock_ctrl == 7) - strcat(str, "133MHz"); } else { strcpy(str, "PCI:"); if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED) From 0d27b42739ee432a66104793e51a23807b372928 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Sat, 11 Mar 2006 18:50:14 -0800 Subject: [PATCH 14/47] [IPV6]: fix ipv6_saddr_score struct element The scope element in the ipv6_saddr_score struct used in ipv6_dev_get_saddr() is an unsigned integer, but __ipv6_addr_src_scope() returns a signed integer (and can return -1). Signed-off-by: Brian Haley Acked-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b7d8822c1be4..19727d941962 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -822,7 +822,7 @@ struct ipv6_saddr_score { int addr_type; unsigned int attrs; int matchlen; - unsigned int scope; + int scope; unsigned int rule; }; From c12743764129e40dc8461afc1096cf175c7c25f2 Mon Sep 17 00:00:00 2001 From: Gregor Maier Date: Sat, 11 Mar 2006 18:51:25 -0800 Subject: [PATCH 15/47] [NETFILTER]: Fix wrong option spelling in Makefile for CONFIG_BRIDGE_EBT_ULOG Signed-off-by: Gregor Maier Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/netfilter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile index 8bf6d9f6e9d3..905087e0d485 100644 --- a/net/bridge/netfilter/Makefile +++ b/net/bridge/netfilter/Makefile @@ -29,4 +29,4 @@ obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o # watchers obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o -obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_ulog.o +obj-$(CONFIG_BRIDGE_EBT_ULOG) += ebt_ulog.o From ba244fe9005323452428fee4b4b7d0c70a06b627 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 11 Mar 2006 18:51:49 -0800 Subject: [PATCH 16/47] [TCP]: Fix tcp_tso_should_defer() when limit>=65536 That's >= a full sized TSO frame, so we should always return 0 in that case. Based upon a report and initial patch from Lachlan Andrew, final patch suggested by Herbert Xu. Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a7623ead39a8..9f498a6c8895 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1036,6 +1036,10 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ limit = min(send_win, cong_win); + /* If a full-sized TSO skb can be sent, do it. */ + if (limit >= 65536) + return 0; + if (sysctl_tcp_tso_win_divisor) { u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); From cdaabbd74b15296acf09215355a7f3b07b92b83e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 12 Mar 2006 22:36:06 +0000 Subject: [PATCH 17/47] [ARM] iwmmxt thread state alignment This patch removes the reliance of iwmmxt on hand coded alignments. Since thread_info is always 8K aligned, specifying that fpstate is 8-byte aligned achieves the same effect without needing to resort to hand coded alignments. Signed-off-by: Russell King --- arch/arm/kernel/asm-offsets.c | 4 +++- arch/arm/kernel/ptrace.c | 14 ++++---------- include/asm-arm/fpstate.h | 4 +++- include/asm-arm/thread_info.h | 2 +- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 0abbce8c70bc..b324dcac1c56 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -57,7 +57,9 @@ int main(void) DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); DEFINE(TI_FPSTATE, offsetof(struct thread_info, fpstate)); DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); - DEFINE(TI_IWMMXT_STATE, (offsetof(struct thread_info, fpstate)+4)&~7); +#ifdef CONFIG_IWMMXT + DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt)); +#endif BLANK(); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); DEFINE(S_R1, offsetof(struct pt_regs, ARM_r1)); diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 7b6256bb590e..bc9e2f8ae326 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -610,15 +610,12 @@ static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp) static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) { struct thread_info *thread = task_thread_info(tsk); - void *ptr = &thread->fpstate; if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) return -ENODATA; iwmmxt_task_disable(thread); /* force it to ram */ - /* The iWMMXt state is stored doubleword-aligned. */ - if (((long) ptr) & 4) - ptr += 4; - return copy_to_user(ufp, ptr, 0x98) ? -EFAULT : 0; + return copy_to_user(ufp, &thread->fpstate.iwmmxt, IWMMXT_SIZE) + ? -EFAULT : 0; } /* @@ -627,15 +624,12 @@ static int ptrace_getwmmxregs(struct task_struct *tsk, void __user *ufp) static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) { struct thread_info *thread = task_thread_info(tsk); - void *ptr = &thread->fpstate; if (!test_ti_thread_flag(thread, TIF_USING_IWMMXT)) return -EACCES; iwmmxt_task_release(thread); /* force a reload */ - /* The iWMMXt state is stored doubleword-aligned. */ - if (((long) ptr) & 4) - ptr += 4; - return copy_from_user(ptr, ufp, 0x98) ? -EFAULT : 0; + return copy_from_user(&thead->fpstate.iwmmxt, ufp, IWMMXT_SIZE) + ? -EFAULT : 0; } #endif diff --git a/include/asm-arm/fpstate.h b/include/asm-arm/fpstate.h index f7430e3aa55d..6246bf83627d 100644 --- a/include/asm-arm/fpstate.h +++ b/include/asm-arm/fpstate.h @@ -55,8 +55,10 @@ struct fp_soft_struct { unsigned int save[FP_SOFT_SIZE]; /* undefined information */ }; +#define IWMMXT_SIZE 0x98 + struct iwmmxt_struct { - unsigned int save[0x98/sizeof(int) + 1]; + unsigned int save[IWMMXT_SIZE / sizeof(unsigned int)]; }; union fp_state { diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index 33a33cbb6329..cfbccb63c67b 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h @@ -59,7 +59,7 @@ struct thread_info { struct cpu_context_save cpu_context; /* cpu context */ __u8 used_cp[16]; /* thread used copro */ unsigned long tp_value; - union fp_state fpstate; + union fp_state fpstate __attribute__((aligned(8))); union vfp_state vfpstate; struct restart_block restart_block; }; From 406dbfc9ae0e6b7eb4da4a52c0a6556a0d7e6a2f Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:32:47 -0800 Subject: [PATCH 18/47] [NETFILTER]: nfnetlink_queue: fix possible NULL-ptr dereference Fix NULL-ptr dereference when a config message for a non-existant queue containing only an NFQA_CFG_PARAMS attribute is received. Coverity #433 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netfilter/nfnetlink_queue.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index cac38b2e147a..2cf5fb8322c4 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c @@ -928,8 +928,12 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, if (nfqa[NFQA_CFG_PARAMS-1]) { struct nfqnl_msg_config_params *params; - params = NFA_DATA(nfqa[NFQA_CFG_PARAMS-1]); + if (!queue) { + ret = -ENOENT; + goto out_put; + } + params = NFA_DATA(nfqa[NFQA_CFG_PARAMS-1]); nfqnl_set_mode(queue, params->copy_mode, ntohl(params->copy_range)); } From f6e57464df7ba0e91a23b0854adb56852dcd58a7 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:33:22 -0800 Subject: [PATCH 19/47] [NET_SCHED]: act_api: fix skb leak in error path The skb is allocated by the function, so it needs to be freed instead of trimmed on overrun. Coverity #614 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/sched/act_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 792ce59940ec..2ffa11c6e8de 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -707,7 +707,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, rtattr_failure: nlmsg_failure: - skb_trim(skb, b - skb->data); + kfree_skb(skb); return -1; } From f8dc01f543f28253abeef649987249210d8db3cc Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:33:49 -0800 Subject: [PATCH 20/47] [XFRM]: Fix leak in ah6_input tmp_hdr is not freed when ipv6_clear_mutable_options fails. Coverity #650 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv6/ah6.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c index c7932cb420a5..84963749ab77 100644 --- a/net/ipv6/ah6.c +++ b/net/ipv6/ah6.c @@ -279,7 +279,7 @@ static int ah6_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc goto out; memcpy(tmp_hdr, skb->nh.raw, hdr_len); if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len)) - goto out; + goto free_out; skb->nh.ipv6h->priority = 0; skb->nh.ipv6h->flow_lbl[0] = 0; skb->nh.ipv6h->flow_lbl[1] = 0; From cc9a06cd8d6fbb69b4d3c46760c132cfe312fb85 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:34:27 -0800 Subject: [PATCH 21/47] [NETLINK]: Fix use-after-free in netlink_recvmsg The skb given to netlink_cmsg_recv_pktinfo is already freed, move it up a few lines. Coverity #948 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/netlink/af_netlink.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 6b9772d95872..59dc7d140600 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1194,6 +1194,9 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, msg->msg_namelen = sizeof(*addr); } + if (nlk->flags & NETLINK_RECV_PKTINFO) + netlink_cmsg_recv_pktinfo(msg, skb); + if (NULL == siocb->scm) { memset(&scm, 0, sizeof(scm)); siocb->scm = &scm; @@ -1205,8 +1208,6 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock, netlink_dump(sk); scm_recv(sock, msg, siocb->scm, flags); - if (nlk->flags & NETLINK_RECV_PKTINFO) - netlink_cmsg_recv_pktinfo(msg, skb); out: netlink_rcv_wake(sk); From 4a1ff6e2bde56cdf176bd54d557b2e15e819f810 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:34:53 -0800 Subject: [PATCH 22/47] [TCP]: tcp_highspeed: fix AIMD table out-of-bounds access Covertiy #547 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/tcp_highspeed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/tcp_highspeed.c b/net/ipv4/tcp_highspeed.c index 63cf7e540847..e0e9d1383c7c 100644 --- a/net/ipv4/tcp_highspeed.c +++ b/net/ipv4/tcp_highspeed.c @@ -125,7 +125,7 @@ static void hstcp_cong_avoid(struct sock *sk, u32 adk, u32 rtt, /* Update AIMD parameters */ if (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd) { while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && - ca->ai < HSTCP_AIMD_MAX) + ca->ai < HSTCP_AIMD_MAX - 1) ca->ai++; } else if (tp->snd_cwnd < hstcp_aimd_vals[ca->ai].cwnd) { while (tp->snd_cwnd > hstcp_aimd_vals[ca->ai].cwnd && From baa829d8926f02ab04be6ec37780810d221c5b4b Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:35:12 -0800 Subject: [PATCH 23/47] [IPV4/6]: Fix UFO error propagation When ufo_append_data fails err is uninitialized, but returned back. Strangely gcc doesn't notice it. Coverity #901 and #902 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/ip_output.c | 7 ++++--- net/ipv6/ip6_output.c | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 57d290d89ec2..8ee4d016740d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -847,10 +847,11 @@ int ip_append_data(struct sock *sk, if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && (rt->u.dst.dev->features & NETIF_F_UFO)) { - if(ip_ufo_append_data(sk, getfrag, from, length, hh_len, - fragheaderlen, transhdrlen, mtu, flags)) + err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, + fragheaderlen, transhdrlen, mtu, + flags); + if (err) goto error; - return 0; } diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index f999edd846a9..5bf70b1442ea 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -944,10 +944,11 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && (rt->u.dst.dev->features & NETIF_F_UFO)) { - if(ip6_ufo_append_data(sk, getfrag, from, length, hh_len, - fragheaderlen, transhdrlen, mtu, flags)) + err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, + fragheaderlen, transhdrlen, mtu, + flags); + if (err) goto error; - return 0; } From 31fe4d331729e9687db84521c3ceb8e43390efcf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Sun, 12 Mar 2006 20:40:43 -0800 Subject: [PATCH 24/47] [NETFILTER]: arp_tables: fix NULL pointer dereference The check is wrong and lets NULL-ptrs slip through since !IS_ERR(NULL) is true. Coverity #190 Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/ipv4/netfilter/arp_tables.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index dd1048be8a01..7d7ab94a7a2e 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -771,7 +771,7 @@ static int get_entries(const struct arpt_get_entries *entries, struct arpt_table *t; t = xt_find_table_lock(NF_ARP, entries->name); - if (t || !IS_ERR(t)) { + if (t && !IS_ERR(t)) { struct xt_table_info *private = t->private; duprintf("t->private->number = %u\n", private->number); From c33d4568aca9028a22857f94f5e0850012b6444b Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sun, 12 Mar 2006 23:52:59 +0100 Subject: [PATCH 25/47] [PATCH] x86-64: Fix up handling of non canonical user RIPs EM64T CPUs have somewhat weird error reporting for non canonical RIPs in SYSRET. We can't handle any exceptions there because the exception handler would end up running on the user stack which is unsafe. To avoid problems any code that might end up with a user touched pt_regs should return using int_ret_from_syscall. int_ret_from_syscall ends up using IRET, which allows safe exceptions. Cc: Ernie Petrides Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/entry.S | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 7c10e9009d61..22cb6ee074b9 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -178,6 +178,12 @@ rff_trace: * Interrupts are off on entry. * Only called from user space. * + * EM64T CPUs have somewhat weird error reporting for non canonical RIPs in SYSRET. + * We can't handle any exceptions there because the exception handler would + * end up running on the user stack which is unsafe. To avoid problems + * any code that might end up with a user touched pt_regs should return + * using int_ret_from_syscall. + * * XXX if we had a free scratch register we could save the RSP into the stack frame * and report it properly in ps. Unfortunately we haven't. */ @@ -254,7 +260,9 @@ sysret_signal: xorl %esi,%esi # oldset -> arg2 call ptregscall_common 1: movl $_TIF_NEED_RESCHED,%edi - jmp sysret_check + /* Stack frame might have been changed. The IRET path does + some additional checks to handle this */ + jmp int_with_check badsys: movq $-ENOSYS,RAX-ARGOFFSET(%rsp) @@ -280,7 +288,8 @@ tracesys: call syscall_trace_leave RESTORE_TOP_OF_STACK %rbx RESTORE_REST - jmp ret_from_sys_call + /* Stack frame might have been changed. Use the more careful IRET path */ + jmp int_ret_from_sys_call CFI_ENDPROC /* @@ -408,25 +417,9 @@ ENTRY(stub_execve) CFI_ADJUST_CFA_OFFSET -8 CFI_REGISTER rip, r11 SAVE_REST - movq %r11, %r15 - CFI_REGISTER rip, r15 FIXUP_TOP_OF_STACK %r11 call sys_execve - GET_THREAD_INFO(%rcx) - bt $TIF_IA32,threadinfo_flags(%rcx) - CFI_REMEMBER_STATE - jc exec_32bit RESTORE_TOP_OF_STACK %r11 - movq %r15, %r11 - CFI_REGISTER rip, r11 - RESTORE_REST - pushq %r11 - CFI_ADJUST_CFA_OFFSET 8 - CFI_REL_OFFSET rip, 0 - ret - -exec_32bit: - CFI_RESTORE_STATE movq %rax,RAX(%rsp) RESTORE_REST jmp int_ret_from_sys_call From 3759fa9c55923f719ae944a3f8fbb029b36f759d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 13 Mar 2006 14:26:12 -0800 Subject: [PATCH 26/47] [TCP]: Fix zero port problem in IPv6 When we link a socket into the hash table, we need to make sure that we set the num/port fields so that it shows us with a non-zero port value in proc/netlink and on the wire. This code and comment is copied over from the IPv4 stack as is. Signed-off-by: Herbert Xu --- net/ipv6/inet6_hashtables.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index 4154f3a8b6cf..bb8ffb8a14c5 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c @@ -87,7 +87,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, struct inet_timewait_sock **twp) { struct inet_hashinfo *hinfo = death_row->hashinfo; - const struct inet_sock *inet = inet_sk(sk); + struct inet_sock *inet = inet_sk(sk); const struct ipv6_pinfo *np = inet6_sk(sk); const struct in6_addr *daddr = &np->rcv_saddr; const struct in6_addr *saddr = &np->daddr; @@ -129,6 +129,10 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row, } unique: + /* Must record num and sport now. Otherwise we will see + * in hash table socket with a funny identity. */ + inet->num = lport; + inet->sport = htons(lport); BUG_TRAP(sk_unhashed(sk)); __sk_add_node(sk, &head->chain); sk->sk_hash = hash; From 3cb4f09fc2e98bbf26f8c900a94bf3910cd4d823 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 13 Mar 2006 21:20:40 -0800 Subject: [PATCH 27/47] [PATCH] mtd_dataflash, fix block vs page erase Fix a bug in the block-erase optimization for Dataflash; it was using block erase even for smaller segments that need page erase. That wouldn't matter for JFFS2, which never erases less than one block (sometimes several blocks), but for other callers it might. Signed-off-by: David Brownell Acked-by: David Woodhouse Acked-by: Thomas Gleixner Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/mtd/devices/mtd_dataflash.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 155737e7483f..a19480d07888 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -178,7 +178,7 @@ static int dataflash_erase(struct mtd_info *mtd, struct erase_info *instr) * we're at a block boundary and need to erase the whole block. */ pageaddr = instr->addr / priv->page_size; - do_block = (pageaddr & 0x7) == 0 && instr->len <= blocksize; + do_block = (pageaddr & 0x7) == 0 && instr->len >= blocksize; pageaddr = pageaddr << priv->page_offset; command[0] = do_block ? OP_ERASE_BLOCK : OP_ERASE_PAGE; From 6acaba8e22bb355409e06d9e7ce4e7bef1bcaa04 Mon Sep 17 00:00:00 2001 From: Michael Hunold Date: Mon, 13 Mar 2006 21:20:41 -0800 Subject: [PATCH 28/47] [PATCH] Restore tuning capabilities in V4L2 MXB driver The behaviour of the all-in-one Video4Linux tuner driver apparently changed. It now wants to know the tv standard, otherwise it refuses to tune. Restore tuning functionality in my driver for the "Multimedia eXtension Board". The all-in-one tuner driver apparently changed its behaviour. Signed-off-by: Michael Hunold Cc: Mauro Carvalho Chehab Cc: Johannes Stezenbach Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/mxb.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c index 8416ceff524b..41715cacf926 100644 --- a/drivers/media/video/mxb.c +++ b/drivers/media/video/mxb.c @@ -1,7 +1,7 @@ /* mxb - v4l2 driver for the Multimedia eXtension Board - Copyright (C) 1998-2003 Michael Hunold + Copyright (C) 1998-2006 Michael Hunold Visit http://www.mihu.de/linux/saa7146/mxb/ for further details about this card. @@ -327,6 +327,7 @@ static int mxb_init_done(struct saa7146_dev* dev) struct video_decoder_init init; struct i2c_msg msg; struct tuner_setup tun_setup; + v4l2_std_id std = V4L2_STD_PAL_BG; int i = 0, err = 0; struct tea6415c_multiplex vm; @@ -361,6 +362,9 @@ static int mxb_init_done(struct saa7146_dev* dev) mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq); + /* set a default video standard */ + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); + /* mute audio on tea6420s */ mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_line[6][0]); mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_line[6][1]); @@ -921,17 +925,21 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) int one = 1; if(V4L2_STD_PAL_I == std->id ) { + v4l2_std_id std = V4L2_STD_PAL_I; DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* unset the 7111 gpio register -- I don't know what this does exactly */ mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } else { + v4l2_std_id std = V4L2_STD_PAL_BG; DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); /* set the 7146 gpio register -- I don't know what this does exactly */ saa7146_write(dev, GPIO_CTRL, 0x00404050); /* set the 7111 gpio register -- I don't know what this does exactly */ mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one); + mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std); } return 0; } From 63e1fd41c7127650d355e7db7dd92890edf5523b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 13 Mar 2006 21:20:42 -0800 Subject: [PATCH 29/47] [PATCH] macintosh: correct AC Power info in /proc/pmu/info Report AC Power present in /proc/pmu/info if there is no battery. Signed-off-by: Olaf Hering Signed-off-by: Benjamin Herrenschmidt , Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/via-pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 6eb93e45fcd3..4a478eb0e27d 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -825,7 +825,7 @@ proc_get_info(char *page, char **start, off_t off, p += sprintf(p, "PMU driver version : %d\n", PMU_DRIVER_VERSION); p += sprintf(p, "PMU firmware version : %02x\n", pmu_version); p += sprintf(p, "AC Power : %d\n", - ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0)); + ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0) || pmu_battery_count == 0); p += sprintf(p, "Battery count : %d\n", pmu_battery_count); return p - page; From f9a3879abf2f1a27c39915e6074b8ff15a24cb55 Mon Sep 17 00:00:00 2001 From: GOTO Masanori Date: Mon, 13 Mar 2006 21:20:44 -0800 Subject: [PATCH 30/47] [PATCH] Fix sigaltstack corruption among cloned threads This patch fixes alternate signal stack corruption among cloned threads with CLONE_SIGHAND (and CLONE_VM) for linux-2.6.16-rc6. The value of alternate signal stack is currently inherited after a call of clone(... CLONE_SIGHAND | CLONE_VM). But if sigaltstack is set by a parent thread, and then if multiple cloned child threads (+ parent threads) call signal handler at the same time, some threads may be conflicted - because they share to use the same alternative signal stack region. Finally they get sigsegv. It's an undesirable race condition. Note that child threads created from NPTL pthread_create() also hit this conflict when the parent thread uses sigaltstack, without my patch. To fix this problem, this patch clears the child threads' sigaltstack information like exec(). This behavior follows the SUSv3 specification. In SUSv3, pthread_create() says "The alternate stack shall not be inherited (when new threads are initialized)". It means that sigaltstack should be cleared when sigaltstack memory space is shared by cloned threads with CLONE_SIGHAND. Note that I chose "if (clone_flags & CLONE_SIGHAND)" line because: - If clone_flags line is not existed, fork() does not inherit sigaltstack. - CLONE_VM is another choice, but vfork() does not inherit sigaltstack. - CLONE_SIGHAND implies CLONE_VM, and it looks suitable. - CLONE_THREAD is another candidate, and includes CLONE_SIGHAND + CLONE_VM, but this flag has a bit different semantics. I decided to use CLONE_SIGHAND. [ Changed to test for CLONE_VM && !CLONE_VFORK after discussion --Linus ] Signed-off-by: GOTO Masanori Cc: Roland McGrath Cc: Ingo Molnar Acked-by: Linus Torvalds Cc: Ulrich Drepper Cc: Jakub Jelinek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/fork.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/kernel/fork.c b/kernel/fork.c index a8eab86de7f1..ccdfbb16c86d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1061,6 +1061,12 @@ static task_t *copy_process(unsigned long clone_flags, */ p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? child_tidptr: NULL; + /* + * sigaltstack should be cleared when sharing the same VM + */ + if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM) + p->sas_ss_sp = p->sas_ss_size = 0; + /* * Syscall tracing should be turned off in the child regardless * of CLONE_PTRACE. From 143f412eb4c7cc48b9eb4381f9133b7d36c68075 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Mar 2006 21:20:46 -0800 Subject: [PATCH 31/47] [PATCH] NFS: Fix a potential panic in O_DIRECT Based on an original patch by Mike O'Connor and Greg Banks of SGI. Mike states: A normal user can panic an NFS client and cause a local DoS with 'judicious'(?) use of O_DIRECT. Any O_DIRECT write to an NFS file where the user buffer starts with a valid mapped page and contains an unmapped page, will crash in this way. I haven't followed the code, but O_DIRECT reads with similar user buffers will probably also crash albeit in different ways. Details: when nfs_get_user_pages() calls get_user_pages(), it detects and correctly handles get_user_pages() returning an error, which happens if the first page covered by the user buffer's address range is unmapped. However, if the first page is mapped but some subsequent page isn't, get_user_pages() will return a positive number which is less than the number of pages requested (this behaviour is sort of analagous to a short write() call and appears to be intentional). nfs_get_user_pages() doesn't detect this and hands off the array of pages (whose last few elements are random rubbish from the newly allocated array memory) to it's caller, whence they go to nfs_direct_write_seg(), which then totally ignores the nr_pages it's given, and calculates its own idea of how many pages are in the array from the user buffer length. Needless to say, when it comes to transmit those uninitialised page* pointers, we see a crash in the network stack. Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/nfs/direct.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 04ab2fc360e7..4e9b3a1b36c5 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -57,6 +57,7 @@ #define NFSDBG_FACILITY NFSDBG_VFS #define MAX_DIRECTIO_SIZE (4096UL << PAGE_SHIFT) +static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty); static kmem_cache_t *nfs_direct_cachep; /* @@ -107,6 +108,15 @@ nfs_get_user_pages(int rw, unsigned long user_addr, size_t size, page_count, (rw == READ), 0, *pages, NULL); up_read(¤t->mm->mmap_sem); + /* + * If we got fewer pages than expected from get_user_pages(), + * the user buffer runs off the end of a mapping; return EFAULT. + */ + if (result >= 0 && result < page_count) { + nfs_free_user_pages(*pages, result, 0); + *pages = NULL; + result = -EFAULT; + } } return result; } From 712917d1c002f820b177683f4fd491289bde3c32 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 13 Mar 2006 21:20:47 -0800 Subject: [PATCH 32/47] [PATCH] SUNRPC: fix a NULL pointer dereference in net/sunrpc/clnt.c The Coverity checker spotted this possible NULL pointer dereference in rpc_new_client(). Signed-off-by: Adrian Bunk Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- net/sunrpc/clnt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index d2f0550c4ba0..d78479782045 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -113,7 +113,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, err = -EINVAL; if (!xprt) - goto out_err; + goto out_no_xprt; if (vers >= program->nrvers || !(version = program->version[vers])) goto out_err; @@ -182,6 +182,7 @@ out_no_path: kfree(clnt); out_err: xprt_destroy(xprt); +out_no_xprt: return ERR_PTR(err); } From c12e87f4652b1ba3be168b4f63a440399b941928 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Mar 2006 21:20:47 -0800 Subject: [PATCH 33/47] [PATCH] NFSv4: fix mount segfault on errors returned that are < -1000 It turns out that nfs4_proc_get_root() may return raw NFSv4 errors instead of mapping them to kernel errors. Problem spotted by Neil Horman Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/nfs/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 984ca3454d04..f8c0066e02e1 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1430,7 +1430,7 @@ static int nfs4_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle, if (status == 0) status = nfs4_do_fsinfo(server, fhandle, info); out: - return status; + return nfs4_map_errors(status); } static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle, struct nfs_fattr *fattr) From e6d83d55698b73b4d5d55d3d7715a4c26030d577 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Mar 2006 21:20:48 -0800 Subject: [PATCH 34/47] [PATCH] SUNRPC: Fix potential deadlock in RPC code In rpc_wake_up() and rpc_wake_up_status(), it is possible for the call to __rpc_wake_up_task() to fail if another thread happens to be calling rpc_wake_up_task() on the same rpc_task. Problem noticed by Bruno Faccini. Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- net/sunrpc/sched.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 802d4fe0f55c..e838d042f7f5 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c @@ -515,16 +515,14 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue) */ void rpc_wake_up(struct rpc_wait_queue *queue) { - struct rpc_task *task; - + struct rpc_task *task, *next; struct list_head *head; + spin_lock_bh(&queue->lock); head = &queue->tasks[queue->maxpriority]; for (;;) { - while (!list_empty(head)) { - task = list_entry(head->next, struct rpc_task, u.tk_wait.list); + list_for_each_entry_safe(task, next, head, u.tk_wait.list) __rpc_wake_up_task(task); - } if (head == &queue->tasks[0]) break; head--; @@ -541,14 +539,13 @@ void rpc_wake_up(struct rpc_wait_queue *queue) */ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status) { + struct rpc_task *task, *next; struct list_head *head; - struct rpc_task *task; spin_lock_bh(&queue->lock); head = &queue->tasks[queue->maxpriority]; for (;;) { - while (!list_empty(head)) { - task = list_entry(head->next, struct rpc_task, u.tk_wait.list); + list_for_each_entry_safe(task, next, head, u.tk_wait.list) { task->tk_status = status; __rpc_wake_up_task(task); } From 30f4e20a0d3492668f5065af582b5af2d1e4256b Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Mon, 13 Mar 2006 21:20:49 -0800 Subject: [PATCH 35/47] [PATCH] NLM: Ensure we do not Oops in the case of an unlock In theory, NLM specs assure us that the server will only reply LCK_GRANTED or LCK_DENIED_GRACE_PERIOD to our NLM_UNLOCK request. In practice, we should not assume this to be the case, and the code will currently Oops if we do. Signed-off-by: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/lockd/clntproc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 220058d8616d..970b6a6aa337 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -662,12 +662,18 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) * reclaimed while we're stuck in the unlock call. */ fl->fl_u.nfs_fl.flags &= ~NFS_LCK_GRANTED; + /* + * Note: the server is supposed to either grant us the unlock + * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either + * case, we want to unlock. + */ + do_vfs_lock(fl); + if (req->a_flags & RPC_TASK_ASYNC) { status = nlmclnt_async_call(req, NLMPROC_UNLOCK, &nlmclnt_unlock_ops); /* Hrmf... Do the unlock early since locks_remove_posix() * really expects us to free the lock synchronously */ - do_vfs_lock(fl); if (status < 0) { nlmclnt_release_lockargs(req); kfree(req); @@ -680,7 +686,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) if (status < 0) return status; - do_vfs_lock(fl); if (resp->status == NLM_LCK_GRANTED) return 0; From ceb2ca9cb0bfd885127fa9a2c27127b3fe1c8f28 Mon Sep 17 00:00:00 2001 From: Dave Peterson Date: Mon, 13 Mar 2006 21:20:50 -0800 Subject: [PATCH 36/47] [PATCH] EDAC: disable sysfs interface - Disable the EDAC sysfs code. The sysfs interface that EDAC presents to user space needs more thought, and is likely to change substantially. Therefore disable it for now so users don't start depending on it in its current form. - Disable the default behavior of calling panic() when an uncorrectible error is detected (since for now, there is no sysfs interface that allows the user to configure this behavior). Signed-off-by: David S. Peterson Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/edac/edac_mc.c | 44 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 262e44544dc8..9c205274c1cb 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -38,6 +38,12 @@ #define EDAC_MC_VERSION "edac_mc Ver: 2.0.0 " __DATE__ +/* For now, disable the EDAC sysfs code. The sysfs interface that EDAC + * presents to user space needs more thought, and is likely to change + * substantially. + */ +#define DISABLE_EDAC_SYSFS + #ifdef CONFIG_EDAC_DEBUG /* Values of 0 to 4 will generate output */ int edac_debug_level = 1; @@ -47,7 +53,7 @@ EXPORT_SYMBOL(edac_debug_level); /* EDAC Controls, setable by module parameter, and sysfs */ static int log_ue = 1; static int log_ce = 1; -static int panic_on_ue = 1; +static int panic_on_ue; static int poll_msec = 1000; static int check_pci_parity = 0; /* default YES check PCI parity */ @@ -77,6 +83,8 @@ static int pci_whitelist_count ; /* START sysfs data and methods */ +#ifndef DISABLE_EDAC_SYSFS + static const char *mem_types[] = { [MEM_EMPTY] = "Empty", [MEM_RESERVED] = "Reserved", @@ -241,6 +249,7 @@ static struct kobj_type ktype_memctrl = { .default_attrs = (struct attribute **) memctrl_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ /* Initialize the main sysfs entries for edac: * /sys/devices/system/edac @@ -251,6 +260,11 @@ static struct kobj_type ktype_memctrl = { * !0 FAILURE */ static int edac_sysfs_memctrl_setup(void) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int err=0; @@ -283,6 +297,7 @@ static int edac_sysfs_memctrl_setup(void) return err; } +#endif /* DISABLE_EDAC_SYSFS */ /* * MC teardown: @@ -290,6 +305,7 @@ static int edac_sysfs_memctrl_setup(void) */ static void edac_sysfs_memctrl_teardown(void) { +#ifndef DISABLE_EDAC_SYSFS debugf0("MC: " __FILE__ ": %s()\n", __func__); /* Unregister the MC's kobject */ @@ -300,8 +316,11 @@ static void edac_sysfs_memctrl_teardown(void) /* Unregister the 'edac' object */ sysdev_class_unregister(&edac_class); +#endif /* DISABLE_EDAC_SYSFS */ } +#ifndef DISABLE_EDAC_SYSFS + /* * /sys/devices/system/edac/pci; * data structures and methods @@ -554,11 +573,18 @@ static struct kobj_type ktype_edac_pci = { .default_attrs = (struct attribute **) edac_pci_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ + /** * edac_sysfs_pci_setup() * */ static int edac_sysfs_pci_setup(void) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int err; @@ -582,16 +608,20 @@ static int edac_sysfs_pci_setup(void) } return err; } - +#endif /* DISABLE_EDAC_SYSFS */ static void edac_sysfs_pci_teardown(void) { +#ifndef DISABLE_EDAC_SYSFS debugf0("MC: " __FILE__ ": %s()\n", __func__); kobject_unregister(&edac_pci_kobj); kobject_put(&edac_pci_kobj); +#endif } +#ifndef DISABLE_EDAC_SYSFS + /* EDAC sysfs CSROW data structures and methods */ /* Set of more detailed csrow attribute show/store functions */ @@ -1045,6 +1075,8 @@ static struct kobj_type ktype_mci = { .default_attrs = (struct attribute **) mci_attr, }; +#endif /* DISABLE_EDAC_SYSFS */ + #define EDAC_DEVICE_SYMLINK "device" /* @@ -1056,6 +1088,11 @@ static struct kobj_type ktype_mci = { * !0 Failure */ static int edac_create_sysfs_mci_device(struct mem_ctl_info *mci) +#ifdef DISABLE_EDAC_SYSFS +{ + return 0; +} +#else { int i; int err; @@ -1124,12 +1161,14 @@ fail: return err; } +#endif /* DISABLE_EDAC_SYSFS */ /* * remove a Memory Controller instance */ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) { +#ifndef DISABLE_EDAC_SYSFS int i; debugf0("MC: " __FILE__ ": %s()\n", __func__); @@ -1146,6 +1185,7 @@ static void edac_remove_sysfs_mci_device(struct mem_ctl_info *mci) kobject_unregister(&mci->edac_mci_kobj); kobject_put(&mci->edac_mci_kobj); +#endif /* DISABLE_EDAC_SYSFS */ } /* END OF sysfs data and methods */ From cbf0ec6ee001ab89471397ac84105b2e3b2fd986 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 14 Mar 2006 08:01:47 -0800 Subject: [PATCH 37/47] Revert "[PATCH] x86-64: Fix up handling of non canonical user RIPs" This reverts commit c33d4568aca9028a22857f94f5e0850012b6444b. Andrew Clayton and Hugh Dickins report that it's broken for them and causes strange page table and slab corruption, and spontaneous reboots. Let's get it right next time. Cc: Andrew Clayton Cc: Hugh Dickins Cc: Andi Kleen Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/entry.S | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 22cb6ee074b9..7c10e9009d61 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S @@ -178,12 +178,6 @@ rff_trace: * Interrupts are off on entry. * Only called from user space. * - * EM64T CPUs have somewhat weird error reporting for non canonical RIPs in SYSRET. - * We can't handle any exceptions there because the exception handler would - * end up running on the user stack which is unsafe. To avoid problems - * any code that might end up with a user touched pt_regs should return - * using int_ret_from_syscall. - * * XXX if we had a free scratch register we could save the RSP into the stack frame * and report it properly in ps. Unfortunately we haven't. */ @@ -260,9 +254,7 @@ sysret_signal: xorl %esi,%esi # oldset -> arg2 call ptregscall_common 1: movl $_TIF_NEED_RESCHED,%edi - /* Stack frame might have been changed. The IRET path does - some additional checks to handle this */ - jmp int_with_check + jmp sysret_check badsys: movq $-ENOSYS,RAX-ARGOFFSET(%rsp) @@ -288,8 +280,7 @@ tracesys: call syscall_trace_leave RESTORE_TOP_OF_STACK %rbx RESTORE_REST - /* Stack frame might have been changed. Use the more careful IRET path */ - jmp int_ret_from_sys_call + jmp ret_from_sys_call CFI_ENDPROC /* @@ -417,9 +408,25 @@ ENTRY(stub_execve) CFI_ADJUST_CFA_OFFSET -8 CFI_REGISTER rip, r11 SAVE_REST + movq %r11, %r15 + CFI_REGISTER rip, r15 FIXUP_TOP_OF_STACK %r11 call sys_execve + GET_THREAD_INFO(%rcx) + bt $TIF_IA32,threadinfo_flags(%rcx) + CFI_REMEMBER_STATE + jc exec_32bit RESTORE_TOP_OF_STACK %r11 + movq %r15, %r11 + CFI_REGISTER rip, r11 + RESTORE_REST + pushq %r11 + CFI_ADJUST_CFA_OFFSET 8 + CFI_REL_OFFSET rip, 0 + ret + +exec_32bit: + CFI_RESTORE_STATE movq %rax,RAX(%rsp) RESTORE_REST jmp int_ret_from_sys_call From 67963132638e67ad3c5aa16765e6f3f2f3cdd85c Mon Sep 17 00:00:00 2001 From: Maneesh Soni Date: Tue, 14 Mar 2006 15:03:14 +0530 Subject: [PATCH 38/47] [PATCH] Plug kdump shutdown race window lapic_shutdown() re-enables interrupts which is un-desirable for panic case, so use local_irq_save() and local_irq_restore() to keep the irqs disabled for kexec on panic case, and close a possible race window while kdump shutdown as shown in this stack trace -- BUG: spinlock lockup on CPU#1, bash/4396, c52781a0 [] _raw_spin_lock+0xb7/0xd2 [] _spin_lock+0x6/0x8 [] scheduler_tick+0xe7/0x328 [] update_process_times+0x51/0x5d [] smp_apic_timer_interrupt+0x4f/0x58 [] lapic_shutdown+0x76/0x7e [] apic_timer_interrupt+0x1c/0x30 [] lapic_shutdown+0x76/0x7e [] machine_crash_shutdown+0x83/0xaa [] crash_kexec+0xc1/0xe3 [] _spin_lock+0x6/0x8 [] crash_kexec+0xad/0xe3 [] __handle_sysrq+0x84/0xfd [] write_sysrq_trigger+0x2c/0x35 [] vfs_write+0xa2/0x13b [] sys_write+0x3b/0x64 [] syscall_call+0x7/0xb Signed-off-by: Maneesh Soni Signed-off-by: Linus Torvalds --- arch/i386/kernel/apic.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index f39e09ef64ec..776c90989e06 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -570,16 +570,18 @@ void __devinit setup_local_APIC(void) */ void lapic_shutdown(void) { + unsigned long flags; + if (!cpu_has_apic) return; - local_irq_disable(); + local_irq_save(flags); clear_local_APIC(); if (enabled_via_apicbase) disable_local_APIC(); - local_irq_enable(); + local_irq_restore(flags); } #ifdef CONFIG_PM From a488edc914aa1d766a4e2c982b5ae03d5657ec1b Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Tue, 14 Mar 2006 13:44:00 -0600 Subject: [PATCH 39/47] [PATCH] JFS: Take logsync lock before testing mp->lsn This fixes a race where lsn could be cleared before taking the lock Signed-off-by: Dave Kleikamp Signed-off-by: Linus Torvalds --- fs/jfs/jfs_dmap.c | 7 ++----- fs/jfs/jfs_imap.c | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c index 2967b7393415..79b5404db100 100644 --- a/fs/jfs/jfs_dmap.c +++ b/fs/jfs/jfs_dmap.c @@ -532,10 +532,10 @@ dbUpdatePMap(struct inode *ipbmap, lastlblkno = lblkno; + LOGSYNC_LOCK(log, flags); if (mp->lsn != 0) { /* inherit older/smaller lsn */ logdiff(diffp, mp->lsn, log); - LOGSYNC_LOCK(log, flags); if (difft < diffp) { mp->lsn = lsn; @@ -548,20 +548,17 @@ dbUpdatePMap(struct inode *ipbmap, logdiff(diffp, mp->clsn, log); if (difft > diffp) mp->clsn = tblk->clsn; - LOGSYNC_UNLOCK(log, flags); } else { mp->log = log; mp->lsn = lsn; /* insert bp after tblock in logsync list */ - LOGSYNC_LOCK(log, flags); - log->count++; list_add(&mp->synclist, &tblk->synclist); mp->clsn = tblk->clsn; - LOGSYNC_UNLOCK(log, flags); } + LOGSYNC_UNLOCK(log, flags); } /* write the last buffer. */ diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c index 31b4aa13dd4b..4efa0d0eec39 100644 --- a/fs/jfs/jfs_imap.c +++ b/fs/jfs/jfs_imap.c @@ -2844,11 +2844,11 @@ diUpdatePMap(struct inode *ipimap, */ lsn = tblk->lsn; log = JFS_SBI(tblk->sb)->log; + LOGSYNC_LOCK(log, flags); if (mp->lsn != 0) { /* inherit older/smaller lsn */ logdiff(difft, lsn, log); logdiff(diffp, mp->lsn, log); - LOGSYNC_LOCK(log, flags); if (difft < diffp) { mp->lsn = lsn; /* move mp after tblock in logsync list */ @@ -2860,17 +2860,15 @@ diUpdatePMap(struct inode *ipimap, logdiff(diffp, mp->clsn, log); if (difft > diffp) mp->clsn = tblk->clsn; - LOGSYNC_UNLOCK(log, flags); } else { mp->log = log; mp->lsn = lsn; /* insert mp after tblock in logsync list */ - LOGSYNC_LOCK(log, flags); log->count++; list_add(&mp->synclist, &tblk->synclist); mp->clsn = tblk->clsn; - LOGSYNC_UNLOCK(log, flags); } + LOGSYNC_UNLOCK(log, flags); write_metapage(mp); return (0); } From 3fb962bde48c413bfa419ec4413037e87955dcb6 Mon Sep 17 00:00:00 2001 From: Nathan Scott Date: Wed, 15 Mar 2006 15:14:45 +1100 Subject: [PATCH 40/47] Fix a direct I/O locking issue revealed by the new mutex code. Affects only XFS (i.e. DIO_OWN_LOCKING case) - currently it is not possible to get i_mutex locking correct when using DIO_OWN direct I/O locking in a filesystem due to indeterminism in the possible return code/lock/unlock combinations. This can cause a direct read to attempt a double i_mutex unlock inside XFS. We're now ensuring __blockdev_direct_IO always exits with the inode i_mutex (still) held for a direct reader. Tested with the three different locking modes (via direct block device access, ext3 and XFS) - both reading and writing; cannot find any regressions resulting from this change, and it clearly fixes the mutex_unlock warning originally reported here: http://marc.theaimsgroup.com/?l=linux-kernel&m=114189068126253&w=2 Signed-off-by: Nathan Scott Acked-by: Christoph Hellwig --- fs/direct-io.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 848044af7e16..27f3e787faca 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1155,15 +1155,16 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, * For writes, i_mutex is not held on entry; it is never taken. * * DIO_LOCKING (simple locking for regular files) - * For writes we are called under i_mutex and return with i_mutex held, even though - * it is internally dropped. + * For writes we are called under i_mutex and return with i_mutex held, even + * though it is internally dropped. * For reads, i_mutex is not held on entry, but it is taken and dropped before * returning. * * DIO_OWN_LOCKING (filesystem provides synchronisation and handling of * uninitialised data, allowing parallel direct readers and writers) * For writes we are called without i_mutex, return without it, never touch it. - * For reads, i_mutex is held on entry and will be released before returning. + * For reads we are called under i_mutex and return with i_mutex held, even + * though it may be internally dropped. * * Additional i_alloc_sem locking requirements described inline below. */ @@ -1182,7 +1183,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, ssize_t retval = -EINVAL; loff_t end = offset; struct dio *dio; - int reader_with_isem = (rw == READ && dio_lock_type == DIO_OWN_LOCKING); + int release_i_mutex = 0; + int acquire_i_mutex = 0; if (rw & WRITE) current->flags |= PF_SYNCWRITE; @@ -1225,7 +1227,6 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, * writers need to grab i_alloc_sem only (i_mutex is already held) * For regular files using DIO_OWN_LOCKING, * neither readers nor writers take any locks here - * (i_mutex is already held and release for writers here) */ dio->lock_type = dio_lock_type; if (dio_lock_type != DIO_NO_LOCKING) { @@ -1236,7 +1237,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, mapping = iocb->ki_filp->f_mapping; if (dio_lock_type != DIO_OWN_LOCKING) { mutex_lock(&inode->i_mutex); - reader_with_isem = 1; + release_i_mutex = 1; } retval = filemap_write_and_wait_range(mapping, offset, @@ -1248,7 +1249,7 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, if (dio_lock_type == DIO_OWN_LOCKING) { mutex_unlock(&inode->i_mutex); - reader_with_isem = 0; + acquire_i_mutex = 1; } } @@ -1269,11 +1270,13 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, nr_segs, blkbits, get_blocks, end_io, dio); if (rw == READ && dio_lock_type == DIO_LOCKING) - reader_with_isem = 0; + release_i_mutex = 0; out: - if (reader_with_isem) + if (release_i_mutex) mutex_unlock(&inode->i_mutex); + else if (acquire_i_mutex) + mutex_lock(&inode->i_mutex); if (rw & WRITE) current->flags &= ~PF_SYNCWRITE; return retval; From e843e280cbe218fc8387339806d344708dee348a Mon Sep 17 00:00:00 2001 From: Greg Smith Date: Tue, 14 Mar 2006 19:50:17 -0800 Subject: [PATCH 41/47] [PATCH] "s390: multiple subchannel sets support" fix It seems this patch got dropped (it was in addition to the `s390: improve response code handling in chsc_enable_facility()' patch). Acked-by: Cornelia Huck Cc: Martin Schwidefsky Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/cio/css.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 1bbf231f8aaf..3c77d65960db 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -409,6 +409,9 @@ __init_channel_subsystem(struct subchannel_id schid, void *data) /* -ENXIO: no more subchannels. */ case -ENXIO: return ret; + /* -EIO: this subchannel set not supported. */ + case -EIO: + return ret; default: return 0; } From 4983da07f1e2e8dc81cb9d640fbf35b899cdbdf2 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 14 Mar 2006 19:50:19 -0800 Subject: [PATCH 42/47] [PATCH] page migration: fail if page is in a vma flagged VM_LOCKED page migration currently simply retries a couple of times if try_to_unmap() fails without inspecting the return code. However, SWAP_FAIL indicates that the page is in a vma that has the VM_LOCKED flag set (if ignore_refs ==1). We can check for that return code and avoid retrying the migration. migrate_page_remove_references() now needs to return a reason why the failure occured. So switch migrate_page_remove_references to use -Exx style error messages. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 6 ++++-- mm/vmscan.c | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 62cfd17dc5fe..a9b399402007 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -3060,6 +3060,7 @@ int buffer_migrate_page(struct page *newpage, struct page *page) { struct address_space *mapping = page->mapping; struct buffer_head *bh, *head; + int rc; if (!mapping) return -EAGAIN; @@ -3069,8 +3070,9 @@ int buffer_migrate_page(struct page *newpage, struct page *page) head = page_buffers(page); - if (migrate_page_remove_references(newpage, page, 3)) - return -EAGAIN; + rc = migrate_page_remove_references(newpage, page, 3); + if (rc) + return rc; bh = head; do { diff --git a/mm/vmscan.c b/mm/vmscan.c index 7ccf763bb30b..4fe7e3aa02e2 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -700,7 +700,7 @@ int migrate_page_remove_references(struct page *newpage, * the page. */ if (!mapping || page_mapcount(page) + nr_refs != page_count(page)) - return 1; + return -EAGAIN; /* * Establish swap ptes for anonymous pages or destroy pte @@ -721,13 +721,15 @@ int migrate_page_remove_references(struct page *newpage, * If the page was not migrated then the PageSwapCache bit * is still set and the operation may continue. */ - try_to_unmap(page, 1); + if (try_to_unmap(page, 1) == SWAP_FAIL) + /* A vma has VM_LOCKED set -> Permanent failure */ + return -EPERM; /* * Give up if we were unable to remove all mappings. */ if (page_mapcount(page)) - return 1; + return -EAGAIN; write_lock_irq(&mapping->tree_lock); @@ -738,7 +740,7 @@ int migrate_page_remove_references(struct page *newpage, if (!page_mapping(page) || page_count(page) != nr_refs || *radix_pointer != page) { write_unlock_irq(&mapping->tree_lock); - return 1; + return -EAGAIN; } /* @@ -813,10 +815,14 @@ EXPORT_SYMBOL(migrate_page_copy); */ int migrate_page(struct page *newpage, struct page *page) { + int rc; + BUG_ON(PageWriteback(page)); /* Writeback must be complete */ - if (migrate_page_remove_references(newpage, page, 2)) - return -EAGAIN; + rc = migrate_page_remove_references(newpage, page, 2); + + if (rc) + return rc; migrate_page_copy(newpage, page); From b4fb376628e63bfc8071fc915b921da3db4a3385 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 14 Mar 2006 19:50:20 -0800 Subject: [PATCH 43/47] [PATCH] Page migration documentation update Update the documentation for page migration. - Fix up bits and pieces in cpusets.txt - Rework text in vm/page-migration to be clearer and reflect the final version of page migration in 2.6.16. Mention Andi Kleen's numactl package that contains user space tools for page migration via libnuma. Add reference to numa_maps and to the manpage in numactl. - Add todo list for outstanding issues Signed-off-by: Christoph Lameter Acked-by: Paul Jackson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/cpusets.txt | 41 ++++------- Documentation/vm/page_migration | 116 ++++++++++++++++++++++---------- 2 files changed, 95 insertions(+), 62 deletions(-) diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 990998ee10b6..30c41459953c 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt @@ -4,8 +4,9 @@ Copyright (C) 2004 BULL SA. Written by Simon.Derr@bull.net -Portions Copyright (c) 2004 Silicon Graphics, Inc. +Portions Copyright (c) 2004-2006 Silicon Graphics, Inc. Modified by Paul Jackson +Modified by Christoph Lameter CONTENTS: ========= @@ -90,7 +91,8 @@ This can be especially valuable on: These subsets, or "soft partitions" must be able to be dynamically adjusted, as the job mix changes, without impacting other concurrently -executing jobs. +executing jobs. The location of the running jobs pages may also be moved +when the memory locations are changed. The kernel cpuset patch provides the minimum essential kernel mechanisms required to efficiently implement such subsets. It @@ -102,8 +104,8 @@ memory allocator code. 1.3 How are cpusets implemented ? --------------------------------- -Cpusets provide a Linux kernel (2.6.7 and above) mechanism to constrain -which CPUs and Memory Nodes are used by a process or set of processes. +Cpusets provide a Linux kernel mechanism to constrain which CPUs and +Memory Nodes are used by a process or set of processes. The Linux kernel already has a pair of mechanisms to specify on which CPUs a task may be scheduled (sched_setaffinity) and on which Memory @@ -371,22 +373,17 @@ cpusets memory placement policy 'mems' subsequently changes. If the cpuset flag file 'memory_migrate' is set true, then when tasks are attached to that cpuset, any pages that task had allocated to it on nodes in its previous cpuset are migrated -to the tasks new cpuset. Depending on the implementation, -this migration may either be done by swapping the page out, -so that the next time the page is referenced, it will be paged -into the tasks new cpuset, usually on the node where it was -referenced, or this migration may be done by directly copying -the pages from the tasks previous cpuset to the new cpuset, -where possible to the same node, relative to the new cpuset, -as the node that held the page, relative to the old cpuset. +to the tasks new cpuset. The relative placement of the page within +the cpuset is preserved during these migration operations if possible. +For example if the page was on the second valid node of the prior cpuset +then the page will be placed on the second valid node of the new cpuset. + Also if 'memory_migrate' is set true, then if that cpusets 'mems' file is modified, pages allocated to tasks in that cpuset, that were on nodes in the previous setting of 'mems', -will be moved to nodes in the new setting of 'mems.' Again, -depending on the implementation, this might be done by swapping, -or by direct copying. In either case, pages that were not in -the tasks prior cpuset, or in the cpusets prior 'mems' setting, -will not be moved. +will be moved to nodes in the new setting of 'mems.' +Pages that were not in the tasks prior cpuset, or in the cpusets +prior 'mems' setting, will not be moved. There is an exception to the above. If hotplug functionality is used to remove all the CPUs that are currently assigned to a cpuset, @@ -434,16 +431,6 @@ and then start a subshell 'sh' in that cpuset: # The next line should display '/Charlie' cat /proc/self/cpuset -In the case that a change of cpuset includes wanting to move already -allocated memory pages, consider further the work of IWAMOTO -Toshihiro for page remapping and memory -hotremoval, which can be found at: - - http://people.valinux.co.jp/~iwamoto/mh.html - -The integration of cpusets with such memory migration is not yet -available. - In the future, a C library interface to cpusets will likely be available. For now, the only way to query or modify cpusets is via the cpuset file system, using the various cd, mkdir, echo, cat, diff --git a/Documentation/vm/page_migration b/Documentation/vm/page_migration index c52820fcf500..0dd4ef30c361 100644 --- a/Documentation/vm/page_migration +++ b/Documentation/vm/page_migration @@ -12,12 +12,18 @@ is running. Page migration allows a process to manually relocate the node on which its pages are located through the MF_MOVE and MF_MOVE_ALL options while setting -a new memory policy. The pages of process can also be relocated +a new memory policy via mbind(). The pages of process can also be relocated from another process using the sys_migrate_pages() function call. The migrate_pages function call takes two sets of nodes and moves pages of a process that are located on the from nodes to the destination nodes. +Page migration functions are provided by the numactl package by Andi Kleen +(a version later than 0.9.3 is required. Get it from +ftp://ftp.suse.com/pub/people/ak). numactl provided libnuma which +provides an interface similar to other numa functionality for page migration. +cat /proc//numa_maps allows an easy review of where the pages of +a process are located. See also the numa_maps manpage in the numactl package. -Manual migration is very useful if for example the scheduler has relocated +Manual migration is useful if for example the scheduler has relocated a process to a processor on a distant node. A batch scheduler or an administrator may detect the situation and move the pages of the process nearer to the new processor. At some point in the future we may have @@ -25,10 +31,12 @@ some mechanism in the scheduler that will automatically move the pages. Larger installations usually partition the system using cpusets into sections of nodes. Paul Jackson has equipped cpusets with the ability to -move pages when a task is moved to another cpuset. This allows automatic -control over locality of a process. If a task is moved to a new cpuset -then also all its pages are moved with it so that the performance of the -process does not sink dramatically (as is the case today). +move pages when a task is moved to another cpuset (See ../cpusets.txt). +Cpusets allows the automation of process locality. If a task is moved to +a new cpuset then also all its pages are moved with it so that the +performance of the process does not sink dramatically. Also the pages +of processes in a cpuset are moved if the allowed memory nodes of a +cpuset are changed. Page migration allows the preservation of the relative location of pages within a group of nodes for all migration techniques which will preserve a @@ -37,22 +45,26 @@ process. This is necessary in order to preserve the memory latencies. Processes will run with similar performance after migration. Page migration occurs in several steps. First a high level -description for those trying to use migrate_pages() and then -a low level description of how the low level details work. +description for those trying to use migrate_pages() from the kernel +(for userspace usage see the Andi Kleen's numactl package mentioned above) +and then a low level description of how the low level details work. -A. Use of migrate_pages() -------------------------- +A. In kernel use of migrate_pages() +----------------------------------- 1. Remove pages from the LRU. Lists of pages to be migrated are generated by scanning over pages and moving them into lists. This is done by - calling isolate_lru_page() or __isolate_lru_page(). + calling isolate_lru_page(). Calling isolate_lru_page increases the references to the page - so that it cannot vanish under us. + so that it cannot vanish while the page migration occurs. + It also prevents the swapper or other scans to encounter + the page. -2. Generate a list of newly allocates page to move the contents - of the first list to. +2. Generate a list of newly allocates page. These pages will contain the + contents of the pages from the first list after page migration is + complete. 3. The migrate_pages() function is called which attempts to do the migration. It returns the moved pages in the @@ -63,13 +75,17 @@ A. Use of migrate_pages() 4. The leftover pages of various types are returned to the LRU using putback_to_lru_pages() or otherwise disposed of. The pages will still have the refcount as - increased by isolate_lru_pages()! + increased by isolate_lru_pages() if putback_to_lru_pages() is not + used! The kernel may want to handle the various cases of failures in + different ways. -B. Operation of migrate_pages() --------------------------------- +B. How migrate_pages() works +---------------------------- -migrate_pages does several passes over its list of pages. A page is moved -if all references to a page are removable at the time. +migrate_pages() does several passes over its list of pages. A page is moved +if all references to a page are removable at the time. The page has +already been removed from the LRU via isolate_lru_page() and the refcount +is increased so that the page cannot be freed while page migration occurs. Steps: @@ -79,36 +95,40 @@ Steps: 3. Make sure that the page has assigned swap cache entry if it is an anonyous page. The swap cache reference is necessary - to preserve the information contain in the page table maps. + to preserve the information contain in the page table maps while + page migration occurs. 4. Prep the new page that we want to move to. It is locked and set to not being uptodate so that all accesses to the new - page immediately lock while we are moving references. + page immediately lock while the move is in progress. -5. All the page table references to the page are either dropped (file backed) - or converted to swap references (anonymous pages). This should decrease the - reference count. +5. All the page table references to the page are either dropped (file + backed pages) or converted to swap references (anonymous pages). + This should decrease the reference count. -6. The radix tree lock is taken +6. The radix tree lock is taken. This will cause all processes trying + to reestablish a pte to block on the radix tree spinlock. 7. The refcount of the page is examined and we back out if references remain otherwise we know that we are the only one referencing this page. 8. The radix tree is checked and if it does not contain the pointer to this - page then we back out. + page then we back out because someone else modified the mapping first. 9. The mapping is checked. If the mapping is gone then a truncate action may be in progress and we back out. -10. The new page is prepped with some settings from the old page so that accesses - to the new page will be discovered to have the correct settings. +10. The new page is prepped with some settings from the old page so that + accesses to the new page will be discovered to have the correct settings. 11. The radix tree is changed to point to the new page. -12. The reference count of the old page is dropped because the reference has now - been removed. +12. The reference count of the old page is dropped because the radix tree + reference is gone. -13. The radix tree lock is dropped. +13. The radix tree lock is dropped. With that lookups become possible again + and other processes will move from spinning on the tree lock to sleeping on + the locked new page. 14. The page contents are copied to the new page. @@ -119,11 +139,37 @@ Steps: 17. Queued up writeback on the new page is triggered. -18. If swap pte's were generated for the page then remove them again. +18. If swap pte's were generated for the page then replace them with real + ptes. This will reenable access for processes not blocked by the page lock. -19. The locks are dropped from the old and new page. +19. The page locks are dropped from the old and new page. + Processes waiting on the page lock can continue. -20. The new page is moved to the LRU. +20. The new page is moved to the LRU and can be scanned by the swapper + etc again. -Christoph Lameter, December 19, 2005. +TODO list +--------- + +- Page migration requires the use of swap handles to preserve the + information of the anonymous page table entries. This means that swap + space is reserved but never used. The maximum number of swap handles used + is determined by CHUNK_SIZE (see mm/mempolicy.c) per ongoing migration. + Reservation of pages could be avoided by having a special type of swap + handle that does not require swap space and that would only track the page + references. Something like that was proposed by Marcelo Tosatti in the + past (search for migration cache on lkml or linux-mm@kvack.org). + +- Page migration unmaps ptes for file backed pages and requires page + faults to reestablish these ptes. This could be optimized by somehow + recording the references before migration and then reestablish them later. + However, there are several locking challenges that have to be overcome + before this is possible. + +- Page migration generates read ptes for anonymous pages. Dirty page + faults are required to make the pages writable again. It may be possible + to generate a pte marked dirty if it is known that the page is dirty and + that this process has the only reference to that page. + +Christoph Lameter, March 8, 2006. From 74c002410548c7cb1744b45d17a5fa21da515b63 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 14 Mar 2006 19:50:21 -0800 Subject: [PATCH 44/47] [PATCH] Consistent capabilites associated with MPOL_MOVE_ALL It seems that setting scheduling policy and priorities is also the kind of thing that might be performed in apps that also use the NUMA API, so it would seem consistent to use CAP_SYS_NICE for NUMA also. So use CAP_SYS_NICE for controlling migration permissions. Signed-off-by: Christoph Lameter Cc: Michael Kerrisk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/mempolicy.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 954981b14303..2a8206009422 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -748,7 +748,7 @@ long do_mbind(unsigned long start, unsigned long len, MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) || mode > MPOL_MAX) return -EINVAL; - if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_RESOURCE)) + if ((flags & MPOL_MF_MOVE_ALL) && !capable(CAP_SYS_NICE)) return -EPERM; if (start & ~PAGE_MASK) @@ -942,20 +942,20 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, */ if ((current->euid != task->suid) && (current->euid != task->uid) && (current->uid != task->suid) && (current->uid != task->uid) && - !capable(CAP_SYS_ADMIN)) { + !capable(CAP_SYS_NICE)) { err = -EPERM; goto out; } task_nodes = cpuset_mems_allowed(task); /* Is the user allowed to access the target nodes? */ - if (!nodes_subset(new, task_nodes) && !capable(CAP_SYS_ADMIN)) { + if (!nodes_subset(new, task_nodes) && !capable(CAP_SYS_NICE)) { err = -EPERM; goto out; } err = do_migrate_pages(mm, &old, &new, - capable(CAP_SYS_ADMIN) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); + capable(CAP_SYS_NICE) ? MPOL_MF_MOVE_ALL : MPOL_MF_MOVE); out: mmput(mm); return err; From f13b83580acef03a36c785dccc534ccdd7e43084 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 15 Mar 2006 17:37:32 +0100 Subject: [PATCH 45/47] [PATCH] fs/namespace.c:dup_namespace(): fix a use after free The Coverity checker spotted the following bug in dup_namespace(): <-- snip --> if (!new_ns->root) { up_write(&namespace_sem); kfree(new_ns); goto out; } ... out: return new_ns; <-- snip --> Callers expect a non-NULL result to not be freed. Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- fs/namespace.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 058a44865beb..39c81a8d6316 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1338,7 +1338,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL); if (!new_ns) - goto out; + return NULL; atomic_set(&new_ns->count, 1); INIT_LIST_HEAD(&new_ns->list); @@ -1352,7 +1352,7 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) if (!new_ns->root) { up_write(&namespace_sem); kfree(new_ns); - goto out; + return NULL; } spin_lock(&vfsmount_lock); list_add_tail(&new_ns->list, &new_ns->root->mnt_list); @@ -1393,7 +1393,6 @@ struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs) if (altrootmnt) mntput(altrootmnt); -out: return new_ns; } From 0df7861240b3484dea52d1f5782c69fd95b6cf23 Mon Sep 17 00:00:00 2001 From: Zhu Yi Date: Tue, 28 Feb 2006 15:10:36 +0800 Subject: [PATCH 46/47] [PATCH] ieee80211: Fix CCMP decryption problem when QoS is enabled Use the correct STYPE for Qos data. Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_crypt_ccmp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c index 470221728503..3840d1911f2b 100644 --- a/net/ieee80211/ieee80211_crypt_ccmp.c +++ b/net/ieee80211/ieee80211_crypt_ccmp.c @@ -131,7 +131,7 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && - (WLAN_FC_GET_STYPE(fc) & 0x08)); + (WLAN_FC_GET_STYPE(fc) & IEEE80211_STYPE_QOS_DATA)); aad_len = 22; if (a4_included) aad_len += 6; From 72df16f109b73be37977a26d342e9103e8851cb6 Mon Sep 17 00:00:00 2001 From: Hong Liu Date: Wed, 8 Mar 2006 10:50:20 +0800 Subject: [PATCH 47/47] [PATCH] ieee80211: Fix QoS is not active problem Fix QoS is not active even the network and the card is QOS enabled. The problem is we pass the wrong ieee80211_network address to ipw_handle_beacon/ipw_handle_probe_response, thus the ieee80211_network->qos_data.active will not be set, causing the driver not sending QoS frames at all. Signed-off-by: Hong Liu Signed-off-by: Zhu Yi Signed-off-by: John W. Linville --- net/ieee80211/ieee80211_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c index b410ab8bcf7a..7ac6a7165d9c 100644 --- a/net/ieee80211/ieee80211_rx.c +++ b/net/ieee80211/ieee80211_rx.c @@ -1417,10 +1417,10 @@ static void ieee80211_process_probe_response(struct ieee80211_device if (is_beacon(beacon->header.frame_ctl)) { if (ieee->handle_beacon != NULL) - ieee->handle_beacon(dev, beacon, &network); + ieee->handle_beacon(dev, beacon, target); } else { if (ieee->handle_probe_response != NULL) - ieee->handle_probe_response(dev, beacon, &network); + ieee->handle_probe_response(dev, beacon, target); } }