2.6.32.23 stable review
Subsystems (47)
cover 2.6.32.23 stable review
This is the start of the stable review cycle for the 2.6.32.23 release. There are 68 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.
Responses should be made by Sunday September 26, 17:00:00 UTC Anything received after that time might be too late.
The whole patch series can be found in one patch at:
kernel.org/pub/linux/kernel/v2.6/stable-review/patch-2.6.32.23-rc1.gz
and the diffstat can be found below.
thanks,
greg k-h
Makefile | 2 +- arch/alpha/kernel/err_marvel.c | 6 +- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- arch/ia64/kernel/fsys.S | 30 ++- arch/mips/include/asm/atomic.h | 24 ++-- arch/mips/mm/tlbex.c | 22 ++- arch/mips/mm/uasm.c | 4 +- arch/mips/mm/uasm.h | 1 + arch/mips/mti-malta/malta-pci.c | 2 + arch/mips/nxp/pnx8550/common/pci.c | 1 + arch/mips/nxp/pnx8550/common/setup.c | 2 +- arch/mips/pci/ops-pmcmsp.c | 1 + arch/mips/pci/pci-yosemite.c | 1 + arch/sparc/include/asm/io_32.h | 4 + arch/sparc/include/asm/io_64.h | 4 + arch/sparc/include/asm/oplib_64.h | 27 +--- arch/sparc/prom/cif.S | 16 +- arch/sparc/prom/console_64.c | 48 ++++- arch/sparc/prom/devops_64.c | 36 +++- arch/sparc/prom/misc_64.c | 314 +++++++++++++++++++++--------- arch/sparc/prom/p1275.c | 102 +---------- arch/sparc/prom/tree_64.c | 210 +++++++++++++++------ arch/x86/include/asm/cmpxchg_32.h | 65 ++----- arch/x86/include/asm/cmpxchg_64.h | 4 +- arch/x86/oprofile/nmi_int.c | 4 +- drivers/acpi/blacklist.c | 14 ++ drivers/ata/pata_pdc202xx_old.c | 15 ++- drivers/char/agp/sis-agp.c | 8 - drivers/char/mem.c | 3 +- drivers/clocksource/sh_tmu.c | 20 +- drivers/input/input.c | 86 +++++++-- drivers/message/fusion/mptscsih.c | 2 + drivers/net/3c503.c | 41 +++- drivers/net/bnx2.c | 20 ++- drivers/net/bonding/bond_3ad.c | 3 + drivers/net/bonding/bond_alb.c | 3 + drivers/net/cxgb3/cxgb3_main.c | 3 + drivers/net/eql.c | 2 + drivers/net/r8169.c | 11 + drivers/net/usb/asix.c | 30 +++- drivers/net/usb/hso.c | 2 + drivers/net/wireless/hostap/hostap_pci.c | 1 + drivers/pci/intel-iommu.c | 90 ++++----- drivers/staging/vt6655/wpactl.c | 11 +- drivers/usb/serial/mos7720.c | 3 + drivers/usb/serial/mos7840.c | 3 + drivers/video/sis/sis_main.c | 3 + drivers/video/via/ioctl.c | 2 + fs/aio.c | 3 + fs/char_dev.c | 4 +- fs/ext4/inode.c | 40 +++-- fs/notify/inotify/inotify_fsnotify.c | 3 + fs/notify/inotify/inotify_user.c | 7 +- fs/partitions/ibm.c | 13 ++- fs/xfs/linux-2.6/xfs_ioctl.c | 2 + include/linux/mm.h | 8 +- include/linux/mmzone.h | 13 ++ include/linux/vmstat.h | 22 ++ include/net/tcp.h | 36 +++- kernel/exit.c | 5 +- kernel/sched.c | 4 +- kernel/sys.c | 2 + mm/memory.c | 15 +- mm/mmap.c | 3 - mm/mmzone.c | 21 ++ mm/page_alloc.c | 33 +++- mm/percpu.c | 2 +- mm/vmstat.c | 15 ++- net/bridge/br_netfilter.c | 9 +- net/core/skbuff.c | 7 +- net/ipv4/tcp.c | 33 +-- net/ipv4/tcp_timer.c | 8 +- net/irda/af_irda.c | 4 +- net/llc/af_llc.c | 3 +- net/rds/recv.c | 2 +- net/sctp/output.c | 1 - net/unix/af_unix.c | 15 ++- security/keys/keyctl.c | 6 +- 78 files changed, 1076 insertions(+), 571 deletions(-)
PATCH 1/68 USB: serial/mos*: prevent reading uninitialized stack memory
2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit a0846f1868b11cd827bdfeaf4527d8b1b1c0b098 upstream.
The TIOCGICOUNT device ioctl in both mos7720.c and mos7840.c allows unprivileged users to read uninitialized stack memory, because the "reserved" member of the serial_icounter_struct struct declared on the stack is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/usb/serial/mos7720.c | 3 +++ drivers/usb/serial/mos7840.c | 3 +++ 2 files changed, 6 insertions(+)
drivers/usb/serial/mos7720.c +3 -0
@@ -1466,6 +1466,9 @@ static int mos7720_ioctl(struct tty_strucase TIOCGICOUNT : cnow = mos7720_port->icount; + +memset (&icount,0 ,sizeof (struct serial_icounter_struct )); + icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng;
drivers/usb/serial/mos7840.c +3 -0
@@ -2287,6 +2287,9 @@ static int mos7840_ioctl(struct tty_strucase TIOCGICOUNT : cnow = mos7840_port->icount;smp_rmb (); + +memset (&icount,0 ,sizeof (struct serial_icounter_struct )); + icount.cts = cnow.cts; icount.dsr = cnow.dsr; icount.rng = cnow.rng;
PATCH 2/68 sparc: Provide io{read,write}{16,32}be().
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
[ Upstream commit 1bff4dbb79a2bc0ee4881c8ea6a4fbed64ea6309 ]
--- arch/sparc/include/asm/io_32.h | 4 ++++ arch/sparc/include/asm/io_64.h | 4 ++++ 2 files changed, 8 insertions(+)
arch/sparc/include/asm/io_32.h +4 -0
@@ -249,10 +249,14 @@ extern void iounmap(volatile void __iome#define ioread8 (X ) readb(X)#define ioread16 (X ) readw(X) +#define ioread16be (X ) __raw_readw(X)#define ioread32 (X ) readl(X) +#define ioread32be (X ) __raw_readl(X)#define iowrite8 (val,X ) writeb(val,X)#define iowrite16 (val,X ) writew(val,X) +#define iowrite16be (val,X ) __raw_writew(val,X)#define iowrite32 (val,X ) writel(val,X) +#define iowrite32be (val,X ) __raw_writel(val,X)static inline void ioread8_rep (void __iomem *port,void *buf,unsigned long count) {
arch/sparc/include/asm/io_64.h +4 -0
@@ -468,10 +468,14 @@ static inline void iounmap(volatile void#define ioread8 (X ) readb(X)#define ioread16 (X ) readw(X) +#define ioread16be (X ) __raw_readw(X)#define ioread32 (X ) readl(X) +#define ioread32be (X ) __raw_readl(X)#define iowrite8 (val,X ) writeb(val,X)#define iowrite16 (val,X ) writew(val,X) +#define iowrite16be (val,X ) __raw_writew(val,X)#define iowrite32 (val,X ) writel(val,X) +#define iowrite32be (val,X ) __raw_writel(val,X)/* Create a virtual mapping cookie for an IO port range */ extern void __iomem *ioport_map (unsigned long port,unsigned int nr);
PATCH 3/68 gro: fix different skb headrooms
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 3d3be4333fdf6faa080947b331a6a19bce1a4f57 ]
Packets entering GRO might have different headrooms, even for a given flow (because of implementation details in drivers, like copybreak). We cant force drivers to deliver packets with a fixed headroom.
1) fix skb_segment()
skb_segment() makes the false assumption headrooms of fragments are same than the head. When CHECKSUM_PARTIAL is used, this can give csum_start errors, and crash later in skb_copy_and_csum_dev()
2) allocate a minimal skb for head of frag_list
skb_gro_receive() uses netdev_alloc_skb(headroom + skb_gro_offset(p)) to allocate a fresh skb. This adds NET_SKB_PAD to a padding already provided by netdevice, depending on various things, like copybreak.
Use alloc_skb() to allocate an exact padding, to reduce cache line needs:NET_SKB_PAD + NET_IP_ALIGN
bugzilla : https://bugzilla.kernel.org/show_bug.cgi?id=16626
Many thanks to Plamen Petrov, testing many debugging patches ! With help of Jarek Poplawski.
--- net/core/skbuff.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/core/skbuff.c +6 -2
@@ -2575,6 +2575,10 @@ struct sk_buff *skb_segment(struct sk_bu__copy_skb_header (nskb, skb); nskb->mac_len = skb->mac_len; +/* nskb and skb might have different headroom */ +if (nskb->ip_summed ==CHECKSUM_PARTIAL ) + nskb->csum_start +=skb_headroom (nskb) - headroom; +skb_reset_mac_header (nskb);skb_set_network_header (nskb, skb->mac_len); nskb->transport_header = (nskb->network_header +
@@ -2704,8 +2708,8 @@ int skb_gro_receive(struct sk_buff **hea }else if (skb_gro_len (p) != pinfo->gso_size)return -E2BIG ; - headroom =skb_headroom (p); - nskb =netdev_alloc_skb (p->dev, headroom +skb_gro_offset (p)); + headroom =NET_SKB_PAD +NET_IP_ALIGN ; + nskb =alloc_skb (headroom +skb_gro_offset (p),GFP_ATOMIC );if (unlikely (!nskb))return -ENOMEM ;
PATCH 4/68 gro: Re-fix different skb headrooms
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jarek Poplawski <[email protected]>
[ Upstream commit 64289c8e6851bca0e589e064c9a5c9fbd6ae5dd4 ]
The patch: "gro: fix different skb headrooms" in its part:
"2) allocate a minimal skb for head of frag_list" is buggy. The copied skb has p->data set at the ip header at the moment, and skb_gro_offset is the length of ip + tcp headers. So, after the change the length of mac header is skipped. Later skb_set_mac_header() sets it into the NET_SKB_PAD area (if it's long enough) and ip header is misaligned at NET_SKB_PAD + NET_IP_ALIGN offset. There is no reason to assume the original skb was wrongly allocated, so let's copy it as it was.
bugzilla : https://bugzilla.kernel.org/show_bug.cgi?id=16626
fixes commit: 3d3be4333fdf6faa080947b331a6a19bce1a4f57
--- net/core/skbuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/skbuff.c +1 -1
@@ -2708,7 +2708,7 @@ int skb_gro_receive(struct sk_buff **hea }else if (skb_gro_len (p) != pinfo->gso_size)return -E2BIG ; - headroom =NET_SKB_PAD +NET_IP_ALIGN ; + headroom =skb_headroom (p); nskb =alloc_skb (headroom +skb_gro_offset (p),GFP_ATOMIC );if (unlikely (!nskb))return -ENOMEM ;
PATCH 5/68 irda: Correctly clean up self->ias_obj on irda_bind() failure.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
[ Upstream commit 628e300cccaa628d8fb92aa28cb7530a3d5f2257 ]
If irda_open_tsap() fails, the irda_bind() code tries to destroy the ->ias_obj object by hand, but does so wrongly.
In particular, it fails to a) release the hashbin attached to the object and b) reset the self->ias_obj pointer to NULL.
Fix both problems by using irias_delete_object() and explicitly setting self->ias_obj to NULL, just as irda_release() does.
--- net/irda/af_irda.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/irda/af_irda.c +2 -2
@@ -810,8 +810,8 @@ static int irda_bind(struct socket *sock err =irda_open_tsap (self, addr->sir_lsap_sel, addr->sir_name);if (err <0 ) { -kfree (self->ias_obj->name); -kfree (self->ias_obj); +irias_delete_object (self->ias_obj); + self->ias_obj =NULL ;return err; }
PATCH 6/68 tcp: select(writefds) dont hang up when a peer close connection
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: KOSAKI Motohiro <[email protected]>
[ Upstream commit d84ba638e4ba3c40023ff997aa5e8d3ed002af36 ]
This issue come from ruby language community. Below test program hang up when only run on Linux.
% uname -mrsv
Linux 2.6.26-2-486 #1 Sat Dec 26 08:37:39 UTC 2009 i686
% ruby -rsocket -ve '
BasicSocket.do_not_reverse_lookup = true
serv = TCPServer.open("127.0.0.1", 0)
s1 = TCPSocket.open("127.0.0.1", serv.addr[1])
s2 = serv.accept
s2.close
s1.write("a") rescue p $!
s1.write("a") rescue p $!
Thread.new {
s1.write("a")
}.join'
ruby 1.9.3dev (2010-07-06 trunk 28554) [i686-linux]
#<Errno::EPIPE: Broken pipe>
[Hang Here]FreeBSD, Solaris, Mac doesn't. because Ruby's write() method call select() internally. and tcp_poll has a bug.
SUS defined 'ready for writing' of select() as following.
| A descriptor shall be considered ready for writing when a call to an output | function with O_NONBLOCK clear would not block, whether or not the function | would transfer data successfully.
That said, EPIPE situation is clearly one of 'ready for writing'.
We don't have read-side issue because tcp_poll() already has read side shutdown care.
| if (sk->sk_shutdown & RCV_SHUTDOWN)
| mask |= POLLIN | POLLRDNORM | POLLRDHUP;
So, Let's insert same logic in write side.
- reference url
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/31065
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/31068
--- net/ipv4/tcp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/ipv4/tcp.c +2 -1
@@ -451,7 +451,8 @@ unsigned int tcp_poll(struct file *file,if (sk_stream_wspace (sk) >=sk_stream_min_wspace (sk)) mask |=POLLOUT |POLLWRNORM ; } - } + }else + mask |=POLLOUT |POLLWRNORM ;if (tp->urg_data &TCP_URG_VALID ) mask |=POLLPRI ;
PATCH 7/68 tcp: Combat per-cpu skew in orphan tests.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
[ Upstream commit ad1af0fedba14f82b240a03fe20eb9b2fdbd0357 ]
As reported by Anton Blanchard when we use percpu_counter_read_positive() to make our orphan socket limit checks, the check can be off by up to num_cpus_online() * batch (which is 32 by default) which on a 128 cpu machine can be as large as the default orphan limit itself.
Fix this by doing the full expensive sum check if the optimized check triggers.
--- include/net/tcp.h | 18 ++++++++++++++---- net/ipv4/tcp.c | 5 +---- net/ipv4/tcp_timer.c | 8 ++++---- 3 files changed, 19 insertions(+), 12 deletions(-)
include/net/tcp.h +14 -4
@@ -259,11 +259,21 @@ static inline int between(__u32 seq1, __return seq3 - seq2 >= seq1 - seq2; } -static inline int tcp_too_many_orphans (struct sock *sk,int num) +static inline bool tcp_too_many_orphans (struct sock *sk,int shift) { -return (num > sysctl_tcp_max_orphans) || - (sk->sk_wmem_queued >SOCK_MIN_SNDBUF && -atomic_read (&tcp_memory_allocated) > sysctl_tcp_mem[2 ]); +struct percpu_counter *ocp = sk->sk_prot->orphan_count; +int orphans =percpu_counter_read_positive (ocp); + +if (orphans << shift > sysctl_tcp_max_orphans) { + orphans =percpu_counter_sum_positive (ocp); +if (orphans << shift > sysctl_tcp_max_orphans) +return true; + } + +if (sk->sk_wmem_queued >SOCK_MIN_SNDBUF && +atomic_read (&tcp_memory_allocated) > sysctl_tcp_mem[2 ]) +return true; +return false; }/* syncookies: remember time of last synqueue overflow */
net/ipv4/tcp.c +1 -4
@@ -1976,11 +1976,8 @@ adjudge_to_death: } }if (sk->sk_state !=TCP_CLOSE ) { -int orphan_count =percpu_counter_read_positive ( - sk->sk_prot->orphan_count); -sk_mem_reclaim (sk); -if (tcp_too_many_orphans (sk, orphan_count)) { +if (tcp_too_many_orphans (sk,0 )) {if (net_ratelimit ())printk (KERN_INFO "TCP: too many of orphaned " "sockets\n" );
net/ipv4/tcp_timer.c +4 -4
@@ -65,18 +65,18 @@ static void tcp_write_err(struct sock *sstatic int tcp_out_of_resources (struct sock *sk,int do_reset) {struct tcp_sock *tp =tcp_sk (sk); -int orphans =percpu_counter_read_positive (&tcp_orphan_count); +int shift =0 ;/* If peer does not open window for long time, or did not transmit * anything for long time, penalize it. */ if ((s32)(tcp_time_stamp - tp->lsndtime) >2 *TCP_RTO_MAX || !do_reset) - orphans <<=1 ; + shift++;/* If some dubious ICMP arrived, penalize even more. */ if (sk->sk_err_soft) - orphans <<=1 ; + shift++; -if (tcp_too_many_orphans (sk, orphans)) { +if (tcp_too_many_orphans (sk, shift)) {if (net_ratelimit ())printk (KERN_INFO "Out of socket memory\n" );
PATCH 8/68 tcp: fix three tcp sysctls tuning
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit c5ed63d66f24fd4f7089b5a6e087b0ce7202aa8e ]
As discovered by Anton Blanchard, current code to autotune tcp_death_row.sysctl_max_tw_buckets, sysctl_tcp_max_orphans and sysctl_max_syn_backlog makes little sense.
The bigger a page is, the less tcp_max_orphans is : 4096 on a 512GB machine in Anton's case.
(tcp_hashinfo.bhash_size * sizeof(struct inet_bind_hashbucket)) is much bigger if spinlock debugging is on. Its wrong to select bigger limits in this case (where kernel structures are also bigger)
bhash_size max is 65536, and we get this value even for small machines.
A better ground is to use size of ehash table, this also makes code shorter and more obvious.
Based on a patch from Anton, and another from David.
--- net/ipv4/tcp.c | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-)
net/ipv4/tcp.c +7 -17
@@ -2878,7 +2878,7 @@ void __init tcp_init(void) {struct sk_buff *skb =NULL ;unsigned long nr_pages, limit; -int order, i, max_share; +int i, max_share, cnt;BUILD_BUG_ON (sizeof (struct tcp_skb_cb ) >sizeof (skb->cb));
@@ -2927,22 +2927,12 @@ void __init tcp_init(void)INIT_HLIST_HEAD (&tcp_hashinfo.bhash[i].chain); } -/* Try to be a bit smarter and adjust defaults depending -* on available memory. -*/ -for (order =0 ; ((1 << order) <<PAGE_SHIFT ) < - (tcp_hashinfo.bhash_size *sizeof (struct inet_bind_hashbucket )); - order++) - ; -if (order >=4 ) { - tcp_death_row.sysctl_max_tw_buckets =180000 ; - sysctl_tcp_max_orphans =4096 << (order -4 ); - sysctl_max_syn_backlog =1024 ; - }else if (order <3 ) { - tcp_death_row.sysctl_max_tw_buckets >>= (3 - order); - sysctl_tcp_max_orphans >>= (3 - order); - sysctl_max_syn_backlog =128 ; - } + + cnt = tcp_hashinfo.ehash_size; + + tcp_death_row.sysctl_max_tw_buckets = cnt /2 ; + sysctl_tcp_max_orphans = cnt /2 ; + sysctl_max_syn_backlog =max (128 , cnt /256 );/* Set the pressure threshold to be a fraction of global memory that * is up to 1/2 at 256 MB, decreasing toward zero with the amount of
PATCH 9/68 bridge: Clear IPCB before possible entry into IP stack
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
[ Upstream commit 17762060c25590bfddd68cc1131f28ec720f405f ]
The bridge protocol lives dangerously by having incestuous relations with the IP stack. In this instance an abomination has been created where a bogus IPCB area from a bridged packet leads to a crash in the IP stack because it's interpreted as IP options.
This patch papers over the problem by clearing the IPCB area in that particular spot. To fix this properly we'd also need to parse any IP options if present but I'm way too lazy for that.
--- net/bridge/br_netfilter.c | 3 +++ 1 file changed, 3 insertions(+)
net/bridge/br_netfilter.c +3 -0
@@ -600,6 +600,9 @@ static unsigned int br_nf_pre_routing(unpskb_trim_rcsum (skb, len); +/* BUG: Should really parse the IP options here. */ +memset (IPCB (skb),0 ,sizeof (struct inet_skb_parm )); +nf_bridge_put (skb->nf_bridge);if (!nf_bridge_alloc (skb))return NF_DROP ;
PATCH 10/68 bridge: Clear INET control block of SKBs passed into ip_fragment().
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
[ Upstream commit 4ce6b9e1621c187a32a47a17bf6be93b1dc4a3df ]
In a similar vain to commit 17762060c25590bfddd68cc1131f28ec720f405f ("bridge: Clear IPCB before possible entry into IP stack")
Any time we call into the IP stack we have to make sure the state there is as expected by the ipv4 code.
With help from Eric Dumazet and Herbert Xu.
--- net/bridge/br_netfilter.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/bridge/br_netfilter.c +4 -2
@@ -800,9 +800,11 @@ static int br_nf_dev_queue_xmit(struct sif (skb->nfct !=NULL && (skb->protocol ==htons (ETH_P_IP ) ||IS_VLAN_IP (skb)) && skb->len > skb->dev->mtu && - !skb_is_gso (skb)) + !skb_is_gso (skb)) { +/* BUG: Should really parse the IP options here. */ +memset (IPCB (skb),0 ,sizeof (struct inet_skb_parm ));return ip_fragment (skb, br_dev_queue_push_xmit); -else + }else return br_dev_queue_push_xmit(skb); }#else
PATCH 11/68 net: Fix oops from tcp_collapse() when using splice()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Steven J. Magnani <[email protected]>
[ Upstream commit baff42ab1494528907bf4d5870359e31711746ae ]
tcp_read_sock() can have a eat skbs without immediately advancing copied_seq. This can cause a panic in tcp_collapse() if it is called as a result of the recv_actor dropping the socket lock.
A userspace program that splices data from a socket to either another socket or to a file can trigger this bug.
--- net/ipv4/tcp.c | 1 + 1 file changed, 1 insertion(+)
net/ipv4/tcp.c +1 -0
@@ -1335,6 +1335,7 @@ int tcp_read_sock(struct sock *sk, read_sk_eat_skb (sk, skb,0 );if (!desc->count)break ; + tp->copied_seq = seq; } tp->copied_seq = seq;
PATCH 12/68 rds: fix a leak of kernel memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit f037590fff3005ce8a1513858d7d44f50053cc8f ]
struct rds_rdma_notify contains a 32 bits hole on 64bit arches, make sure it is zeroed before copying it to user.
--- net/rds/recv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/rds/recv.c +1 -1
@@ -296,7 +296,7 @@ static int rds_still_queued(struct rds_sint rds_notify_queue_get (struct rds_sock *rs,struct msghdr *msghdr) {struct rds_notifier *notifier; -struct rds_rdma_notify cmsg; +struct rds_rdma_notify cmsg = {0 };/* fill holes with zero */ unsigned int count =0 , max_messages = ~0U ;unsigned long flags;LIST_HEAD (copy);
David Miller
maintainerRe: [12/68] rds: fix a leak of kernel memory
From: Greg KH <[email protected]>
Date: Fri, 24 Sep 2010 09:31:36 -0700
Quoted 1 line
2.6.32-stable review patch. If anyone has any objections, please let us know.
No objections.
PATCH 13/68 tcp: Prevent overzealous packetization by SWS logic.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Alexey Kuznetsov <[email protected]>
[ Upstream commit 01f83d69844d307be2aa6fea88b0e8fe5cbdb2f4 ]
If peer uses tiny MSS (say, 75 bytes) and similarly tiny advertised window, the SWS logic will packetize to half the MSS unnecessarily.
This causes problems with some embedded devices.
However for large MSS devices we do want to half-MSS packetize otherwise we never get enough packets into the pipe for things like fast retransmit and recovery to work.
Be careful also to handle the case where MSS > window, otherwise we'll never send until the probe timer.
--- include/net/tcp.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
include/net/tcp.h +16 -2
@@ -511,8 +511,22 @@ extern unsigned int tcp_current_mss(stru/* Bound MSS / TSO packet size with the half of the window */ static inline int tcp_bound_to_half_wnd (struct tcp_sock *tp,int pktsize) { -if (tp->max_window && pktsize > (tp->max_window >>1 )) -return max (tp->max_window >>1 ,68U - tp->tcp_header_len); +int cutoff; + +/* When peer uses tiny windows, there is no use in packetizing +* to sub-MSS pieces for the sake of SWS or making sure there +* are enough packets in the pipe for fast recovery. +* +* On the other hand, for extremely large MSS devices, handling +* smaller than MSS windows in this way does make sense. +*/ +if (tp->max_window >=512 ) + cutoff = (tp->max_window >>1 ); +else + cutoff = tp->max_window; + +if (cutoff && pktsize > cutoff) +return max_t (int, cutoff,68U - tp->tcp_header_len);else return pktsize; }
PATCH 14/68 UNIX: Do not loop forever at unix_autobind().
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tetsuo Handa <[email protected]>
[ Upstream commit a9117426d0fcc05a194f728159a2d43df43c7add ]
We assumed that unix_autobind() never fails if kzalloc() succeeded. But unix_autobind() allows only 1048576 names. If /proc/sys/fs/file-max is larger than 1048576 (e.g. systems with more than 10GB of RAM), a local user can consume all names using fork()/socket()/bind().
If all names are in use, those who call bind() with addr_len == sizeof(short) or connect()/sendmsg() with setsockopt(SO_PASSCRED) will continue
while (1)
yield();loop at unix_autobind() till a name becomes available.
This patch adds a loop counter in order to give up after 1048576 attempts.
Calling yield() for once per 256 attempts may not be sufficient when many names are already in use, for __unix_find_socket_byname() can take long time under such circumstance. Therefore, this patch also adds cond_resched() call.
Note that currently a local user can consume 2GB of kernel memory if the user is allowed to create and autobind 1048576 UNIX domain sockets. We should consider adding some restriction for autobind operation.
--- net/unix/af_unix.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
net/unix/af_unix.c +12 -3
@@ -671,6 +671,7 @@ static int unix_autobind(struct socket *static u32 ordernum =1 ;struct unix_address *addr;int err; +unsigned int retries =0 ;mutex_lock (&u->readlock);
@@ -696,9 +697,17 @@ retry:if (__unix_find_socket_byname (net, addr->name, addr->len, sock->type, addr->hash)) {spin_unlock (&unix_table_lock); -/* Sanity yield. It is unusual case, but yet... */ -if (!(ordernum&0xFF )) -yield (); +/* +* __unix_find_socket_byname() may take long time if many names +* are already in use. +*/ +cond_resched (); +/* Give up if all names seems to be in use. */ +if (retries++ ==0xFFFFF ) { + err = -ENOSPC ; +kfree (addr); + goto out; + } goto retry; } addr->hash ^= sk->sk_type;
PATCH 15/68 r8169: fix random mdio_write failures
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Timo Teräs <[email protected]>
[ Upstream commit 024a07bacf8287a6ddfa83e9d5b951c5e8b4070e ]
Some configurations need delay between the "write completed" indication and new write to work reliably.
Realtek driver seems to use longer delay when polling the "write complete" bit, so it waits long enough between writes with high probability (but could probably break too). This patch adds a new udelay to make sure we wait unconditionally some time after the write complete indication.
This caused a regression with XID 18000000 boards when the board specific phy configuration writing many mdio registers was added in commit 2e955856ff (r8169: phy init for the 8169scd). Some of the configration mdio writes would almost always fail, and depending on failure might leave the PHY in non-working state.
--- drivers/net/r8169.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/net/r8169.c +5 -0
@@ -557,6 +557,11 @@ static void mdio_write(void __iomem *ioabreak ;udelay (25 ); } +/* +* Some configurations require a small delay even after the write +* completed indication or the next write might fail. +*/ +udelay (25 ); }static int mdio_read (void __iomem *ioaddr,int reg_addr)
PATCH 16/68 r8169: fix mdio_read and update mdio_write according to hw specs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Timo Teräs <[email protected]>
[ Upstream commit 81a95f049962ec20a9aed888e676208b206f0f2e ]
Realtek confirmed that a 20us delay is needed after mdio_read and mdio_write operations. Reduce the delay in mdio_write, and add it to mdio_read too. Also add a comment that the 20us is from hw specs.
--- drivers/net/r8169.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
drivers/net/r8169.c +9 -3
@@ -558,10 +558,10 @@ static void mdio_write(void __iomem *ioaudelay (25 ); }/* -* Some configurations require a small delay even after the write -* completed indication or the next write might fail. +* According to hardware specs a 20us delay is required after write +* complete indication, but before sending next command. */ -udelay (25 ); +udelay (20 ); }static int mdio_read (void __iomem *ioaddr,int reg_addr)
@@ -581,6 +581,12 @@ static int mdio_read(void __iomem *ioadd }udelay (25 ); } +/* +* According to hardware specs a 20us delay is required after read +* complete indication, but before sending next command. +*/ +udelay (20 ); +return value; }
PATCH 17/68 sparc64: Get rid of indirect p1275 PROM call buffer.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David S. Miller <[email protected]>
[ Upstream commit 25edd6946a1d74e5e77813c2324a0908c68bcf9e ]
This is based upon a report by Meelis Roos showing that it's possible that we'll try to fetch a property that is 32K in size with some devices. With the current fixed 3K buffer we use for moving data in and out of the firmware during PROM calls, that simply won't work.
In fact, it will scramble random kernel data during bootup.
The reasoning behind the temporary buffer is entirely historical. It used to be the case that we had problems referencing dynamic kernel memory (including the stack) early in the boot process before we explicitly told the firwmare to switch us over to the kernel trap table.
So what we did was always give the firmware buffers that were locked into the main kernel image.
But we no longer have problems like that, so get rid of all of this indirect bounce buffering.
Besides fixing Meelis's bug, this also makes the kernel data about 3K smaller.
It was also discovered during these conversions that the implementation of prom_retain() was completely wrong, so that was fixed here as well. Currently that interface is not in use.
--- arch/sparc/include/asm/oplib_64.h | 27 --- arch/sparc/prom/cif.S | 16 - arch/sparc/prom/console_64.c | 48 ++++- arch/sparc/prom/devops_64.c | 36 +++- arch/sparc/prom/misc_64.c | 314 ++++++++++++++++++++++++++------------ arch/sparc/prom/p1275.c | 102 ------------ arch/sparc/prom/tree_64.c | 210 ++++++++++++++++++------- 7 files changed, 456 insertions(+), 297 deletions(-)
arch/sparc/include/asm/oplib_64.h +3 -24
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_ char *buf, int buflen);/* Retain physical memory to the caller across soft resets. */ -extern unsigned long prom_retain (const char *name, -unsigned long pa_low,unsigned long pa_high, -long size,long align); +extern int prom_retain (const char *name,unsigned long size, +unsigned long align,unsigned long *paddr);/* Load explicit I/D TLB entries into the calling processor. */ extern long prom_itlb_load(unsigned long index,
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(extern int prom_ihandle2path (int handle,char *buffer,int bufsize);/* Client interface level routines. */ -extern long p1275_cmd (const char *,long , ...); - -#if 0 -#define P1275_SIZE (x) ((((long)((x) / 32)) << 32) | (x)) -#else -#define P1275_SIZE (x) x -#endif - -/* We support at most 16 input and 1 output argument */ -#define P1275_ARG_NUMBER 0 -#define P1275_ARG_IN_STRING 1 -#define P1275_ARG_OUT_BUF 2 -#define P1275_ARG_OUT_32B 3 -#define P1275_ARG_IN_FUNCTION 4 -#define P1275_ARG_IN_BUF 5 -#define P1275_ARG_IN_64B 6 - -#define P1275_IN (x) ((x) & 0xf) -#define P1275_OUT (x) (((x) << 4) & 0xf0) -#define P1275_INOUT (i,o) (P1275_IN(i)|P1275_OUT(o)) -#define P1275_ARG (n,x) ((x) << ((n)*3 + 8)) +extern void p1275_cmd_direct (unsigned long *);#endif /* !(__SPARC64_OPLIB_H) */
arch/sparc/prom/cif.S +8 -8
@@ -9,18 +9,18 @@ #include <asm/thread_info.h> .text - .globl prom_cif_interface -prom_cif_interface: - sethi %hi(p1275buf), %o0 - or %o0, %lo(p1275buf), %o0 - ldx [%o0 + 0x010], %o1 ! prom_cif_stack - save %o1, -192, %sp - ldx [%i0 + 0x008], %l2 ! prom_cif_handler + .globl prom_cif_direct +prom_cif_direct: + sethi %hi(p1275buf), %o1 + or %o1, %lo(p1275buf), %o1 + ldx [%o1 + 0x0010], %o2 ! prom_cif_stack + save %o2, -192, %sp + ldx [%i1 + 0x0008], %l2 ! prom_cif_handler mov %g4, %l0 mov %g5, %l1 mov %g6, %l3 call %l2 - add %i0, 0x018, %o0 ! prom_args + mov %i0, %o0 ! prom_args mov %l0, %g4 mov %l1, %g5 mov %l3, %g6
arch/sparc/prom/console_64.c +37 -11
70 lines not on this page · raw message
arch/sparc/prom/devops_64.c +31 -5
@@ -18,16 +18,32 @@int prom_devopen (const char *dstr) { -return p1275_cmd ("open" ,P1275_ARG (0 ,P1275_ARG_IN_STRING )| -P1275_INOUT (1 ,1 ), - dstr); +unsigned long args[5 ]; + + args[0 ] = (unsigned long )"open" ; + args[1 ] =1 ; + args[2 ] =1 ; + args[3 ] = (unsigned long ) dstr; + args[4 ] = (unsigned long )-1 ; + +p1275_cmd_direct (args); + +return (int ) args[4 ]; }/* Close the device described by device handle 'dhandle'. */ int prom_devclose (int dhandle) { -p1275_cmd ("close" ,P1275_INOUT (1 ,0 ), dhandle); +unsigned long args[4 ]; + + args[0 ] = (unsigned long )"close" ; + args[1 ] =1 ; + args[2 ] =0 ; + args[3 ] = (unsigned int ) dhandle; + +p1275_cmd_direct (args); +return 0 ; }
@@ -37,5 +53,15 @@ prom_devclose(int dhandle)void prom_seek (int dhandle,unsigned int seekhi,unsigned int seeklo) { -p1275_cmd ("seek" ,P1275_INOUT (3 ,1 ), dhandle, seekhi, seeklo); +unsigned long args[7 ]; + + args[0 ] = (unsigned long )"seek" ; + args[1 ] =3 ; + args[2 ] =1 ; + args[3 ] = (unsigned int ) dhandle; + args[4 ] = seekhi; + args[5 ] = seeklo; + args[6 ] = (unsigned long )-1 ; + +p1275_cmd_direct (args); }
arch/sparc/prom/misc_64.c +220 -94
464 lines not on this page · raw message
arch/sparc/prom/p1275.c +3 -99
130 lines not on this page · raw message
arch/sparc/prom/tree_64.c +154 -56
354 lines not on this page · raw message
PATCH 18/68 drivers/net/usb/hso.c: prevent reading uninitialized memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 7011e660938fc44ed86319c18a5954e95a82ab3e upstream.
Fixed formatting (tabs and line breaks).
The TIOCGICOUNT device ioctl allows unprivileged users to read uninitialized stack memory, because the "reserved" member of the serial_icounter_struct struct declared on the stack in hso_get_count() is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/net/usb/hso.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/usb/hso.c +2 -0
@@ -1634,6 +1634,8 @@ static int hso_get_count(struct hso_seristruct uart_icount cnow;struct hso_tiocmget *tiocmget = serial->tiocmget; +memset (&icount,0 ,sizeof (struct serial_icounter_struct )); +if (!tiocmget)return -ENOENT ;spin_lock_irq (&serial->serial_lock);
PATCH 19/68 drivers/net/cxgb3/cxgb3_main.c: prevent reading uninitialized stack memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 49c37c0334a9b85d30ab3d6b5d1acb05ef2ef6de upstream.
Fixed formatting (tabs and line breaks).
The CHELSIO_GET_QSET_NUM device ioctl allows unprivileged users to read 4 bytes of uninitialized stack memory, because the "addr" member of the ch_reg struct declared on the stack in cxgb_extension_ioctl() is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/net/cxgb3/cxgb3_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/cxgb3/cxgb3_main.c +2 -0
@@ -2274,6 +2274,8 @@ static int cxgb_extension_ioctl(struct ncase CHELSIO_GET_QSET_NUM :{struct ch_reg edata; +memset (&edata,0 ,sizeof (struct ch_reg )); + edata.cmd =CHELSIO_GET_QSET_NUM ; edata.val = pi->nqsets;if (copy_to_user (useraddr, &edata,sizeof (edata)))
PATCH 20/68 drivers/net/eql.c: prevent reading uninitialized stack memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit 44467187dc22fdd33a1a06ea0ba86ce20be3fe3c upstream.
Fixed formatting (tabs and line breaks).
The EQL_GETMASTRCFG device ioctl allows unprivileged users to read 16 bytes of uninitialized stack memory, because the "master_name" member of the master_config_t struct declared on the stack in eql_g_master_cfg() is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/net/eql.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/eql.c +2 -0
@@ -554,6 +554,8 @@ static int eql_g_master_cfg(struct net_dequalizer_t *eql;master_config_t mc; +memset (&mc,0 ,sizeof (master_config_t)); +if (eql_is_master (dev)) { eql =netdev_priv (dev); mc.max_slaves = eql->max_slaves;
PATCH 21/68 bonding: correctly process non-linear skbs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andy Gospodarek <[email protected]>
commit ab12811c89e88f2e66746790b1fe4469ccb7bdd9 upstream.
It was recently brought to my attention that 802.3ad mode bonds would no longer form when using some network hardware after a driver update. After snooping around I realized that the particular hardware was using page-based skbs and found that skb->data did not contain a valid LACPDU as it was not stored there. That explained the inability to form an 802.3ad-based bond. For balance-alb mode bonds this was also an issue as ARPs would not be properly processed.
This patch fixes the issue in my tests and should be applied to 2.6.36 and as far back as anyone cares to add it to stable.
Thanks to Alexander Duyck <[email protected]> and Jesse Brandeburg <[email protected]> for the suggestions on this one.
--- drivers/net/bonding/bond_3ad.c | 3 +++ drivers/net/bonding/bond_alb.c | 3 +++ 2 files changed, 6 insertions(+)
drivers/net/bonding/bond_3ad.c +3 -0
@@ -2451,6 +2451,9 @@ int bond_3ad_lacpdu_recv(struct sk_buffif (!(dev->flags &IFF_MASTER )) goto out; +if (!pskb_may_pull (skb,sizeof (struct lacpdu ))) + goto out; +read_lock (&bond->lock); slave =bond_get_slave_by_dev ((struct bonding *)netdev_priv (dev), orig_dev);
drivers/net/bonding/bond_alb.c +3 -0
@@ -370,6 +370,9 @@ static int rlb_arp_recv(struct sk_buff * goto out; } +if (!pskb_may_pull (skb,arp_hdr_len (bond_dev))) + goto out; +if (skb->len <sizeof (struct arp_pkt )) {pr_debug ("Packet is too small to be an ARP\n" ); goto out;
PATCH 22/68 Staging: vt6655: fix buffer overflow
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Carpenter <[email protected]>
commit dd173abfead903c7df54e977535973f3312cd307 upstream.
"param->u.wpa_associate.wpa_ie_len" comes from the user. We should check it so that the copy_from_user() doesn't overflow the buffer.
Also further down in the function, we assume that if "param->u.wpa_associate.wpa_ie_len" is set then "abyWPAIE[0]" is initialized. To make that work, I changed the test here to say that if "wpa_ie_len" is set then "wpa_ie" has to be a valid pointer or we return -EINVAL.
Oddly, we only use the first element of the abyWPAIE[] array. So I suspect there may be some other issues in this function.
--- drivers/staging/vt6655/wpactl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
drivers/staging/vt6655/wpactl.c +8 -3
@@ -767,9 +767,14 @@ static int wpa_set_associate(PSDevice pDDBG_PRT (MSG_LEVEL_DEBUG ,KERN_INFO "wpa_ie_len = %d\n" , param->u.wpa_associate.wpa_ie_len); -if (param->u.wpa_associate.wpa_ie && -copy_from_user (&abyWPAIE[0 ], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) -return -EINVAL ; +if (param->u.wpa_associate.wpa_ie_len) { +if (!param->u.wpa_associate.wpa_ie) +return -EINVAL ; +if (param->u.wpa_associate.wpa_ie_len >sizeof (abyWPAIE)) +return -EINVAL ; +if (copy_from_user (&abyWPAIE[0 ], param->u.wpa_associate.wpa_ie, param->u.wpa_associate.wpa_ie_len)) +return -EFAULT ; + }if (param->u.wpa_associate.mode ==1 ) pMgmt->eConfigMode =WMAC_CONFIG_IBSS_STA ;
PATCH 23/68 net/llc: make opt unsigned in llc_ui_setsockopt()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Carpenter <[email protected]>
commit 339db11b219f36cf7da61b390992d95bb6b7ba2e upstream.
The members of struct llc_sock are unsigned so if we pass a negative value for "opt" it can cause a sign bug. Also it can cause an integer overflow when we multiply "opt * HZ".
--- net/llc/af_llc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/llc/af_llc.c +2 -1
@@ -977,7 +977,8 @@ static int llc_ui_setsockopt(struct sock {struct sock *sk = sock->sk;struct llc_sock *llc =llc_sk (sk); -int rc = -EINVAL , opt; +unsigned int opt; +int rc = -EINVAL ;lock_sock (sk);if (unlikely (level !=SOL_LLC || optlen !=sizeof (int )))
PATCH 24/68 pid: make setpgid() system call use RCU read-side critical section
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Paul E. McKenney <[email protected]>
commit 950eaaca681c44aab87a46225c9e44f902c080aa upstream.
[ 23.584719]
[ 23.584720] ===================================================
[ 23.585059] [ INFO: suspicious rcu_dereference_check() usage. ]
[ 23.585176] ---------------------------------------------------
[ 23.585176] kernel/pid.c:419 invoked rcu_dereference_check() without protection!
[ 23.585176]
[ 23.585176] other info that might help us debug this:
[ 23.585176]
[ 23.585176]
[ 23.585176] rcu_scheduler_active = 1, debug_locks = 1
[ 23.585176] 1 lock held by rc.sysinit/728:
[ 23.585176] #0: (tasklist_lock){.+.+..}, at: [<ffffffff8104771f>] sys_setpgid+0x5f/0x193
[ 23.585176]
[ 23.585176] stack backtrace:
[ 23.585176] Pid: 728, comm: rc.sysinit Not tainted 2.6.36-rc2 #2
[ 23.585176] Call Trace:
[ 23.585176] [<ffffffff8105b436>] lockdep_rcu_dereference+0x99/0xa2
[ 23.585176] [<ffffffff8104c324>] find_task_by_pid_ns+0x50/0x6a
[ 23.585176] [<ffffffff8104c35b>] find_task_by_vpid+0x1d/0x1f
[ 23.585176] [<ffffffff81047727>] sys_setpgid+0x67/0x193
[ 23.585176] [<ffffffff810029eb>] system_call_fastpath+0x16/0x1b
[ 24.959669] type=1400 audit(1282938522.956:4): avc: denied { module_request } for pid=766 comm="hwclock" kmod="char-major-10-135" scontext=system_u:system_r:hwclock_t:s0 tcontext=system_u:system_r:kernel_t:s0 tclasIt turns out that the setpgid() system call fails to enter an RCU read-side critical section before doing a PID-to-task_struct translation. This commit therefore does rcu_read_lock() before the translation, and also does rcu_read_unlock() after the last use of the returned pointer.
--- kernel/sys.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/sys.c +2 -0
@@ -962,6 +962,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid pgid = pid;if (pgid <0 )return -EINVAL ; +rcu_read_lock ();/* From this point forward we keep holding onto the tasklist lock * so that our parent does not change from under us. -DaveM
@@ -1015,6 +1016,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid out:/* All paths lead to here, thus we are safe. -DaveM */ write_unlock_irq (&tasklist_lock); +rcu_read_unlock ();return err; }
PATCH 25/68 sched: Fix user time incorrectly accounted as system time on 32-bit
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Stanislaw Gruszka <[email protected]>
commit e75e863dd5c7d96b91ebbd241da5328fc38a78cc upstream.
We have 32-bit variable overflow possibility when multiply in task_times() and thread_group_times() functions. When the overflow happens then the scaled utime value becomes erroneously small and the scaled stime becomes i erroneously big.
Reported here:
https://bugzilla.redhat.com/show_bug.cgi?id=633037
https://bugzilla.kernel.org/show_bug.cgi?id=16559
LKML-Reference: <[email protected]>
--- kernel/sched.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
kernel/sched.c +2 -2
@@ -5341,9 +5341,9 @@ void thread_group_times(struct task_stru rtime =nsecs_to_cputime (cputime.sum_exec_runtime);if (total) { -u64 temp; +u64 temp = rtime; - temp = (u64)(rtime * cputime.utime); + temp *= cputime.utime;do_div (temp, total); utime = (cputime_t )temp; }else
PATCH 26/68 oprofile: Add Support for Intel CPU Family 6 / Model 22 (Intel Celeron 540)
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick Simmons <[email protected]>
commit c33f543d320843e1732534c3931da4bbd18e6c14 upstream.
This patch adds CPU type detection for the Intel Celeron 540, which is part of the Core 2 family according to Wikipedia; the family and ID pair is absent from the Volume 3B table referenced in the source code comments. I have tested this patch on an Intel Celeron 540 machine reporting itself as Family 6 Model 22, and OProfile runs on the machine without issue.
Spec:
http://download.intel.com/design/mobile/SPECUPDT/317667.pdf
--- arch/x86/oprofile/nmi_int.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/x86/oprofile/nmi_int.c +3 -1
@@ -621,7 +621,9 @@ static int __init ppro_init(char **cpu_tcase 14 : *cpu_type ="i386/core" ;break ; -case 15 :case 23 : +case 0x0f : +case 0x16 : +case 0x17 : *cpu_type ="i386/core_2" ;break ;case 0x1a :
PATCH 27/68 char: Mark /dev/zero and /dev/kmem as not capable of writeback
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jan Kara <[email protected]>
commit 371d217ee1ff8b418b8f73fb2a34990f951ec2d4 upstream.
These devices don't do any writeback but their device inodes still can get dirty so mark bdi appropriately so that bdi code does the right thing and files inodes to lists of bdi carrying the device inodes.
--- drivers/char/mem.c | 3 ++- fs/char_dev.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-)
drivers/char/mem.c +2 -1
@@ -822,10 +822,11 @@ static const struct file_operations zero/* * capabilities for /dev/zero * - permits private mappings, "copies" are taken of the source of zeros +* - no writeback happens */ static struct backing_dev_info zero_bdi = { .name ="char/mem" , - .capabilities =BDI_CAP_MAP_COPY , + .capabilities =BDI_CAP_MAP_COPY |BDI_CAP_NO_ACCT_AND_WRITEBACK , };static const struct file_operations full_fops = {
fs/char_dev.c +3 -1
@@ -39,7 +39,9 @@ struct backing_dev_info directly_mappabl#endif /* permit direct mmap, for read, write or exec */ BDI_CAP_MAP_DIRECT | - BDI_CAP_READ_MAP | BDI_CAP_WRITE_MAP | BDI_CAP_EXEC_MAP), +BDI_CAP_READ_MAP |BDI_CAP_WRITE_MAP |BDI_CAP_EXEC_MAP | +/* no writeback happens */ + BDI_CAP_NO_ACCT_AND_WRITEBACK), };static struct kobj_map *cdev_map;
PATCH 28/68 drivers/pci/intel-iommu.c: fix build with older gccs
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andrew Morton <[email protected]>
commit df08cdc7ef606509debe7677c439be0ca48790e4 upstream.
drivers/pci/intel-iommu.c: In function `__iommu_calculate_agaw':drivers/pci/intel-iommu.c:437: sorry, unimplemented: inlining failed in call to 'width_to_agaw': function body not available drivers/pci/intel-iommu.c:445: sorry, unimplemented: called from here
Move the offending function (and its siblings) to top-of-file, remove the forward declaration.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=17441
--- drivers/pci/intel-iommu.c | 90 +++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 47 deletions(-)
drivers/pci/intel-iommu.c +43 -47
@@ -71,6 +71,49 @@#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64)) +/* page table handling */ +#define LEVEL_STRIDE (9) +#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) + +static inline int agaw_to_level (int agaw) +{ +return agaw +2 ; +} + +static inline int agaw_to_width (int agaw) +{ +return 30 + agaw *LEVEL_STRIDE ; +} + +static inline int width_to_agaw (int width) +{ +return (width -30 ) /LEVEL_STRIDE ; +} + +static inline unsigned int level_to_offset_bits (int level) +{ +return (level -1 ) *LEVEL_STRIDE ; +} + +static inline int pfn_level_offset (unsigned long pfn,int level) +{ +return (pfn >>level_to_offset_bits (level)) &LEVEL_MASK ; +} + +static inline unsigned long level_mask (int level) +{ +return -1UL <<level_to_offset_bits (level); +} + +static inline unsigned long level_size (int level) +{ +return 1UL <<level_to_offset_bits (level); +} + +static inline unsigned long align_to_level (unsigned long pfn,int level) +{ +return (pfn +level_size (level) -1 ) &level_mask (level); +}/* VT-d pages must always be _smaller_ than MM pages. Otherwise things are never going to work. */
@@ -449,8 +492,6 @@ void free_iova_mem(struct iova *iova) } -static inline int width_to_agaw (int width); -static int __iommu_calculate_agaw (struct intel_iommu *iommu,int max_gaw) {unsigned long sagaw;
@@ -664,51 +705,6 @@ out:spin_unlock_irqrestore (&iommu->lock, flags); } -/* page table handling */ -#define LEVEL_STRIDE (9) -#define LEVEL_MASK (((u64)1 << LEVEL_STRIDE) - 1) - -static inline int agaw_to_level (int agaw) -{ -return agaw +2 ; -} - -static inline int agaw_to_width (int agaw) -{ -return 30 + agaw *LEVEL_STRIDE ; - -} - -static inline int width_to_agaw (int width) -{ -return (width -30 ) /LEVEL_STRIDE ; -} - -static inline unsigned int level_to_offset_bits (int level) -{ -return (level -1 ) *LEVEL_STRIDE ; -} - -static inline int pfn_level_offset (unsigned long pfn,int level) -{ -return (pfn >>level_to_offset_bits (level)) &LEVEL_MASK ; -} - -static inline unsigned long level_mask (int level) -{ -return -1UL <<level_to_offset_bits (level); -} - -static inline unsigned long level_size (int level) -{ -return 1UL <<level_to_offset_bits (level); -} - -static inline unsigned long align_to_level (unsigned long pfn,int level) -{ -return (pfn +level_size (level) -1 ) &level_mask (level); -} -static struct dma_pte *pfn_to_dma_pte (struct dmar_domain *domain,unsigned long pfn) {
PATCH 29/68 drivers/video/sis/sis_main.c: prevent reading uninitialized stack memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit fd02db9de73faebc51240619c7c7f99bee9f65c7 upstream.
The FBIOGET_VBLANK device ioctl allows unprivileged users to read 16 bytes of uninitialized stack memory, because the "reserved" member of the fb_vblank struct declared on the stack is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/video/sis/sis_main.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/video/sis/sis_main.c +3 -0
@@ -1701,6 +1701,9 @@ static int sisfb_ioctl(struct fb_info *ibreak ;case FBIOGET_VBLANK : + +memset (&sisvbblank,0 ,sizeof (struct fb_vblank )); + sisvbblank.count =0 ; sisvbblank.flags =sisfb_setupvbblankflags (ivideo, &sisvbblank.vcount, &sisvbblank.hcount);
PATCH 30/68 percpu: fix pcpu_last_unit_cpu
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tejun Heo <[email protected]>
commit 46b30ea9bc3698bc1d1e6fd726c9601d46fa0a91 upstream.
pcpu_first/last_unit_cpu are used to track which cpu has the first and last units assigned. This in turn is used to determine the span of a chunk for man/unmap cache flushes and whether an address belongs to the first chunk or not in per_cpu_ptr_to_phys().
When the number of possible CPUs isn't power of two, a chunk may contain unassigned units towards the end of a chunk. The logic to determine pcpu_last_unit_cpu was incorrect when there was an unused unit at the end of a chunk. It failed to ignore the unused unit and assigned the unused marker NR_CPUS to pcpu_last_unit_cpu.
This was discovered through kdump failure which was caused by malfunctioning per_cpu_ptr_to_phys() on a kvm setup with 50 possible CPUs by CAI Qian.
--- mm/percpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/percpu.c +1 -1
@@ -1702,9 +1702,9 @@ int __init pcpu_setup_first_chunk(constif (pcpu_first_unit_cpu ==NR_CPUS ) pcpu_first_unit_cpu = cpu; + pcpu_last_unit_cpu = cpu; } } - pcpu_last_unit_cpu = cpu; pcpu_nr_units = unit;for_each_possible_cpu (cpu)
PATCH 31/68 aio: check for multiplication overflow in do_io_submit
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jeff Moyer <[email protected]>
commit 75e1c70fc31490ef8a373ea2a4bea2524099b478 upstream.
Tavis Ormandy pointed out that do_io_submit does not do proper bounds checking on the passed-in iocb array:
if (unlikely(nr < 0))
return -EINVAL;
if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(iocbpp))))) return -EFAULT; ^^^^^^^^^^^^^^^^^^
The attached patch checks for overflow, and if it is detected, the number of iocbs submitted is scaled down to a number that will fit in the long. This is an ok thing to do, as sys_io_submit is documented as returning the number of iocbs submitted, so callers should handle a return value of less than the 'nr' argument passed in.
--- fs/aio.c | 3 +++ 1 file changed, 3 insertions(+)
fs/aio.c +3 -0
@@ -1639,6 +1639,9 @@ SYSCALL_DEFINE3(io_submit, aio_context_tif (unlikely (nr <0 ))return -EINVAL ; +if (unlikely (nr >LONG_MAX /sizeof (*iocbpp))) + nr =LONG_MAX /sizeof (*iocbpp); +if (unlikely (!access_ok (VERIFY_READ , iocbpp, (nr*sizeof (*iocbpp)))))return -EFAULT ;
PATCH 32/68 inotify: send IN_UNMOUNT events
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Eric Paris <[email protected]>
commit 611da04f7a31b2208e838be55a42c7a1310ae321 upstream.
Since the .31 or so notify rewrite inotify has not sent events about inodes which are unmounted. This patch restores those events.
--- fs/notify/inotify/inotify_user.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
fs/notify/inotify/inotify_user.c +5 -2
@@ -106,8 +106,11 @@ static inline __u32 inotify_arg_to_mask( {__u32 mask; -/* everything should accept their own ignored and cares about children */ - mask = (FS_IN_IGNORED |FS_EVENT_ON_CHILD ); +/* +* everything should accept their own ignored, cares about children, +* and should receive events when the inode is unmounted +*/ + mask = (FS_IN_IGNORED |FS_EVENT_ON_CHILD |FS_UNMOUNT );/* mask off the flags used to open the fd */ mask |= (arg & (IN_ALL_EVENTS |IN_ONESHOT ));
PATCH 33/68 SCSI: mptsas: fix hangs caused by ATA pass-through
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ryan Kuester <[email protected]>
commit 2a1b7e575b80ceb19ea50bfa86ce0053ea57181d upstream.
I may have an explanation for the LSI 1068 HBA hangs provoked by ATA pass-through commands, in particular by smartctl.
First, my version of the symptoms. On an LSI SAS1068E B3 HBA running 01.29.00.00 firmware, with SATA disks, and with smartd running, I'm seeing occasional task, bus, and host resets, some of which lead to hard faults of the HBA requiring a reboot. Abusively looping the smartctl command,
# while true; do smartctl -a /dev/sdb > /dev/null; done
dramatically increases the frequency of these failures to nearly one per minute. A high IO load through the HBA while looping smartctl seems to improve the chance of a full scsi host reset or a non-recoverable hang.
I reduced what smartctl was doing down to a simple test case which causes the hang with a single IO when pointed at the sd interface. See the code at the bottom of this e-mail. It uses an SG_IO ioctl to issue a single pass-through ATA identify device command. If the buffer userspace gives for the read data has certain alignments, the task is issued to the HBA but the HBA fails to respond. If run against the sg interface, neither the test code nor smartctl causes a hang.
sd and sg handle the SG_IO ioctl slightly differently. Unless you specifically set a flag to do direct IO, sg passes a buffer of its own, which is page-aligned, to the block layer and later copies the result into the userspace buffer regardless of its alignment. sd, on the other hand, always does direct IO unless the userspace buffer fails an alignment test at block/blk-map.c line 57, in which case a page-aligned buffer is created and used for the transfer.
The alignment test currently checks for word-alignment, the default setup by scsi_lib.c; therefore, userspace buffers of almost any alignment are given directly to the HBA as DMA targets. The LSI 1068 hardware doesn't seem to like at least a couple of the alignments which cross a page boundary (see the test code below). Curiously, many page-boundary-crossing alignments do work just fine.
So, either the hardware has an bug handling certain alignments or the hardware has a stricter alignment requirement than the driver is advertising. If stricter alignment is required, then in no case should misaligned buffers from userspace be allowed through without being bounced or at least causing an error to be returned.
It seems the mptsas driver could use blk_queue_dma_alignment() to advertise a stricter alignment requirement. If it does, sd does the right thing and bounces misaligned buffers (see block/blk-map.c line 57). The following patch to 2.6.34-rc5 makes my symptoms go away. I'm sure this is the wrong place for this code, but it gets my idea across.
--- drivers/message/fusion/mptscsih.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/message/fusion/mptscsih.c +2 -0
@@ -2439,6 +2439,8 @@ mptscsih_slave_configure(struct scsi_dev ioc->name,sdev->tagged_supported, sdev->simple_tags, sdev->ordered_tags)); +blk_queue_dma_alignment (sdev->request_queue,512 -1 ); +return 0 ; }
PATCH 34/68 ext4: Fix remaining racy updates of EXT4_I(inode)->i_flags
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Monakhov <[email protected]>
commit 84a8dce2710cc425089a2b92acc354d4fbb5788d upstream.
A few functions were still modifying i_flags in a racy manner.
--- fs/ext4/inode.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-)
fs/ext4/inode.c +22 -16
@@ -4815,20 +4815,26 @@ void ext4_set_inode_flags(struct inode */* Propagate flags from i_flags to EXT4_I(inode)->i_flags */ void ext4_get_inode_flags (struct ext4_inode_info *ei) { -unsigned int flags = ei->vfs_inode.i_flags; +unsigned int vfs_fl; +unsigned long old_fl, new_fl; - ei->i_flags &= ~(EXT4_SYNC_FL |EXT4_APPEND_FL | -EXT4_IMMUTABLE_FL |EXT4_NOATIME_FL |EXT4_DIRSYNC_FL ); -if (flags &S_SYNC ) - ei->i_flags |=EXT4_SYNC_FL ; -if (flags &S_APPEND ) - ei->i_flags |=EXT4_APPEND_FL ; -if (flags &S_IMMUTABLE ) - ei->i_flags |=EXT4_IMMUTABLE_FL ; -if (flags &S_NOATIME ) - ei->i_flags |=EXT4_NOATIME_FL ; -if (flags &S_DIRSYNC ) - ei->i_flags |=EXT4_DIRSYNC_FL ; +do { + vfs_fl = ei->vfs_inode.i_flags; + old_fl = ei->i_flags; + new_fl = old_fl & ~(EXT4_SYNC_FL |EXT4_APPEND_FL | +EXT4_IMMUTABLE_FL |EXT4_NOATIME_FL | +EXT4_DIRSYNC_FL ); +if (vfs_fl &S_SYNC ) + new_fl |=EXT4_SYNC_FL ; +if (vfs_fl &S_APPEND ) + new_fl |=EXT4_APPEND_FL ; +if (vfs_fl &S_IMMUTABLE ) + new_fl |=EXT4_IMMUTABLE_FL ; +if (vfs_fl &S_NOATIME ) + new_fl |=EXT4_NOATIME_FL ; +if (vfs_fl &S_DIRSYNC ) + new_fl |=EXT4_DIRSYNC_FL ; + }while (cmpxchg (&ei->i_flags, old_fl, new_fl) != old_fl); } static blkcnt_t ext4_inode_blocks(struct ext4_inode *raw_inode,
@@ -5067,7 +5073,7 @@ static int ext4_inode_blocks_set(handle_*/ raw_inode->i_blocks_lo =cpu_to_le32 (i_blocks); raw_inode->i_blocks_high =0 ; - ei->i_flags &= ~EXT4_HUGE_FILE_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_HUGE_FILE );return 0 ; }if (!EXT4_HAS_RO_COMPAT_FEATURE (sb,EXT4_FEATURE_RO_COMPAT_HUGE_FILE ))
@@ -5080,9 +5086,9 @@ static int ext4_inode_blocks_set(handle_*/ raw_inode->i_blocks_lo =cpu_to_le32 (i_blocks); raw_inode->i_blocks_high =cpu_to_le16 (i_blocks >>32 ); - ei->i_flags &= ~EXT4_HUGE_FILE_FL ; +ext4_clear_inode_flag (inode,EXT4_INODE_HUGE_FILE ); }else { - ei->i_flags |=EXT4_HUGE_FILE_FL ; +ext4_set_inode_flag (inode,EXT4_INODE_HUGE_FILE );/* i_block is stored in file system block size */ i_blocks = i_blocks >> (inode->i_blkbits -9 ); raw_inode->i_blocks_lo =cpu_to_le32 (i_blocks);
PATCH 35/68 IA64: fix siglock
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tony Luck <[email protected]>
commit f574c843191728d9407b766a027f779dcd27b272 upstream.
When ia64 converted to using ticket locks, an inline implementation of trylock/unlock in fsys.S was missed. This was not noticed because in most circumstances it simply resulted in using the slow path because the siglock was apparently not available (under old spinlock rules).
Problems occur when the ticket spinlock has value 0x0 (when first initialised, or when it wraps around). At this point the fsys.S code acquires the lock (changing the 0x0 to 0x1. If another process attempts to get the lock at this point, it will change the value from 0x1 to 0x2 (using new ticket lock rules). Then the fsys.S code will free the lock using old spinlock rules by writing 0x0 to it. From here a variety of bad things can happen.
--- arch/ia64/kernel/fsys.S | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-)
arch/ia64/kernel/fsys.S +39 -7
@@ -424,14 +424,26 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP #ifdef CONFIG_SMP - mov r17=1 - ;; - cmpxchg4.acq r18=[r31],r17,ar.ccv // try to acquire the lock + // __ticket_spin_trylock(r31) + ld4 r17=[r31] mov r8=EINVAL // default to EINVAL ;; + extr r9=r17,17,15 + ;; + xor r18=r17,r9 + adds r19=1,r17 + ;; + extr.u r18=r18,0,15 + ;; + cmp.eq p0,p7=0,r18 +(p7) br.cond.spnt.many .lock_contention + mov.m ar.ccv=r17 + ;; + cmpxchg4.acq r9=[r31],r19,ar.ccv + ;; + cmp4.eq p0,p7=r9,r17 +(p7) br.cond.spnt.many .lock_contention ld8 r3=[r2] // re-read current->blocked now that we hold the lock - cmp4.ne p6,p0=r18,r0 -(p6) br.cond.spnt.many .lock_contention ;; #else ld8 r3=[r2] // re-read current->blocked now that we hold the lock
@@ -490,7 +502,17 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 (p6) br.cond.spnt.few 1b // yes -> retry #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + adds r31=2,r31 + ;; + ld2.bias r2=[r31] + mov r3=65534 + ;; + adds r2=2,r2 + ;; + and r3=r3,r2 + ;; + st2.rel [r31]=r3 #endif SSM_PSR_I(p0, p9, r31) ;;
@@ -512,7 +534,17 @@ EX(.fail_efault, (p15) st8 [r34]=r3) .sig_pending: #ifdef CONFIG_SMP - st4.rel [r31]=r0 // release the lock + // __ticket_spin_unlock(r31) + adds r31=2,r31 + ;; + ld2.bias r2=[r31] + mov r3=65534 + ;; + adds r2=2,r2 + ;; + and r3=r3,r2 + ;; + st2.rel [r31]=r3 #endif SSM_PSR_I(p0, p9, r17) ;;
PATCH 36/68 IA64: Optimize ticket spinlocks in fsys_rt_sigprocmask
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Petr Tesarik <[email protected]>
commit 2d2b6901649a62977452be85df53eda2412def24 upstream.
Tony's fix (f574c843191728d9407b766a027f779dcd27b272) has a small bug, it incorrectly uses "r3" as a scratch register in the first of the two unlock paths ... it is also inefficient. Optimize the fast path again.
--- arch/ia64/kernel/fsys.S | 42 +++++++++++------------------------------- 1 file changed, 11 insertions(+), 31 deletions(-)
arch/ia64/kernel/fsys.S +11 -31
@@ -420,34 +420,31 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 ;; RSM_PSR_I(p0, r18, r19) // mask interrupt delivery - mov ar.ccv=0 andcm r14=r14,r17 // filter out SIGKILL & SIGSTOP + mov r8=EINVAL // default to EINVAL #ifdef CONFIG_SMP // __ticket_spin_trylock(r31) ld4 r17=[r31] - mov r8=EINVAL // default to EINVAL - ;; - extr r9=r17,17,15 ;; - xor r18=r17,r9 + mov.m ar.ccv=r17 + extr.u r9=r17,17,15 adds r19=1,r17 + extr.u r18=r17,0,15 ;; - extr.u r18=r18,0,15 + cmp.eq p6,p7=r9,r18 ;; - cmp.eq p0,p7=0,r18 +(p6) cmpxchg4.acq r9=[r31],r19,ar.ccv +(p6) dep.z r20=r19,1,15 // next serving ticket for unlock (p7) br.cond.spnt.many .lock_contention - mov.m ar.ccv=r17 - ;; - cmpxchg4.acq r9=[r31],r19,ar.ccv ;; cmp4.eq p0,p7=r9,r17 + adds r31=2,r31 (p7) br.cond.spnt.many .lock_contention ld8 r3=[r2] // re-read current->blocked now that we hold the lock ;; #else ld8 r3=[r2] // re-read current->blocked now that we hold the lock - mov r8=EINVAL // default to EINVAL #endif add r18=IA64_TASK_PENDING_OFFSET+IA64_SIGPENDING_SIGNAL_OFFSET,r16 add r19=IA64_TASK_SIGNAL_OFFSET,r16
@@ -503,16 +500,8 @@ EX(.fail_efault, ld8 r14=[r33]) // r14 #ifdef CONFIG_SMP // __ticket_spin_unlock(r31) - adds r31=2,r31 - ;; - ld2.bias r2=[r31] - mov r3=65534 - ;; - adds r2=2,r2 - ;; - and r3=r3,r2 - ;; - st2.rel [r31]=r3 + st2.rel [r31]=r20 + mov r20=0 // i must not leak kernel bits... #endif SSM_PSR_I(p0, p9, r31) ;;
@@ -535,16 +524,7 @@ EX(.fail_efault, (p15) st8 [r34]=r3) .sig_pending: #ifdef CONFIG_SMP // __ticket_spin_unlock(r31) - adds r31=2,r31 - ;; - ld2.bias r2=[r31] - mov r3=65534 - ;; - adds r2=2,r2 - ;; - and r3=r3,r2 - ;; - st2.rel [r31]=r3 + st2.rel [r31]=r20 // release the lock #endif SSM_PSR_I(p0, p9, r17) ;;
PATCH 37/68 KEYS: Fix RCU no-lock warning in keyctl_session_to_parent()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Howells <[email protected]>
commit 9d1ac65a9698513d00e5608d93fca0c53f536c14 upstream.
There's an protected access to the parent process's credentials in the middle of keyctl_session_to_parent(). This results in the following RCU warning:
===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
security/keys/keyctl.c:1291 invoked rcu_dereference_check() without protection!
other info that might help us debug this:
rcu_scheduler_active = 1, debug_locks = 0
1 lock held by keyctl-session-/2137:
#0: (tasklist_lock){.+.+..}, at: [<ffffffff811ae2ec>] keyctl_session_to_parent+0x60/0x236
stack backtrace: Pid: 2137, comm: keyctl-session- Not tainted 2.6.36-rc2-cachefs+ #1 Call Trace: [<ffffffff8105606a>] lockdep_rcu_dereference+0xaa/0xb3 [<ffffffff811ae379>] keyctl_session_to_parent+0xed/0x236 [<ffffffff811af77e>] sys_keyctl+0xb4/0xb6 [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
The code should take the RCU read lock to make sure the parents credentials don't go away, even though it's holding a spinlock and has IRQ disabled.
--- security/keys/keyctl.c | 3 +++ 1 file changed, 3 insertions(+)
security/keys/keyctl.c +3 -0
@@ -1259,6 +1259,7 @@ long keyctl_session_to_parent(void) keyring_r =NULL ; me = current; +rcu_read_lock ();write_lock_irq (&tasklist_lock); parent = me->real_parent;
@@ -1313,6 +1314,7 @@ long keyctl_session_to_parent(void)set_ti_thread_flag (task_thread_info (parent),TIF_NOTIFY_RESUME );write_unlock_irq (&tasklist_lock); +rcu_read_unlock ();if (oldcred)put_cred (oldcred);return 0 ;
@@ -1321,6 +1323,7 @@ already_same: ret =0 ; not_permitted:write_unlock_irq (&tasklist_lock); +rcu_read_unlock ();put_cred (cred);return ret;
PATCH 38/68 KEYS: Fix bug in keyctl_session_to_parent() if parent has no session keyring
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Howells <[email protected]>
commit 3d96406c7da1ed5811ea52a3b0905f4f0e295376 upstream.
Fix a bug in keyctl_session_to_parent() whereby it tries to check the ownership of the parent process's session keyring whether or not the parent has a session keyring [CVE-2010-2960].
This results in the following oops:
BUG: unable to handle kernel NULL pointer dereference at 00000000000000a0 IP: [<ffffffff811ae4dd>] keyctl_session_to_parent+0x251/0x443 ... Call Trace: [<ffffffff811ae2f3>] ? keyctl_session_to_parent+0x67/0x443 [<ffffffff8109d286>] ? __do_fault+0x24b/0x3d0 [<ffffffff811af98c>] sys_keyctl+0xb4/0xb8 [<ffffffff81001eab>] system_call_fastpath+0x16/0x1b
if the parent process has no session keyring.
If the system is using pam_keyinit then it mostly protected against this as all processes derived from a login will have inherited the session keyring created by pam_keyinit during the log in procedure.
To test this, pam_keyinit calls need to be commented out in /etc/pam.d/.
--- security/keys/keyctl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
security/keys/keyctl.c +2 -1
@@ -1292,7 +1292,8 @@ long keyctl_session_to_parent(void) goto not_permitted;/* the keyrings must have the same UID */ -if (pcred ->tgcred->session_keyring->uid != mycred->euid || +if ((pcred->tgcred->session_keyring && + pcred->tgcred->session_keyring->uid != mycred->euid) || mycred->tgcred->session_keyring->uid != mycred->euid) goto not_permitted;
PATCH 39/68 xfs: prevent reading uninitialized stack memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit a122eb2fdfd78b58c6dd992d6f4b1aaef667eef9 upstream.
The XFS_IOC_FSGETXATTR ioctl allows unprivileged users to read 12 bytes of uninitialized stack memory, because the fsxattr struct declared on the stack in xfs_ioc_fsgetxattr() does not alter (or zero) the 12-byte fsx_pad member before copying it back to the user. This patch takes care of it.
--- fs/xfs/linux-2.6/xfs_ioctl.c | 2 ++ 1 file changed, 2 insertions(+)
fs/xfs/linux-2.6/xfs_ioctl.c +2 -0
@@ -789,6 +789,8 @@ xfs_ioc_fsgetxattr( {struct fsxattr fa; +memset (&fa,0 ,sizeof (struct fsxattr )); +xfs_ilock (ip,XFS_ILOCK_SHARED ); fa.fsx_xflags =xfs_ip2xflags (ip); fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
PATCH 40/68 drivers/video/via/ioctl.c: prevent reading uninitialized stack memory
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dan Rosenberg <[email protected]>
commit b4aaa78f4c2f9cde2f335b14f4ca30b01f9651ca upstream.
The VIAFB_GET_INFO device ioctl allows unprivileged users to read 246 bytes of uninitialized stack memory, because the "reserved" member of the viafb_ioctl_info struct declared on the stack is not altered or zeroed before being copied back to the user. This patch takes care of it.
--- drivers/video/via/ioctl.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/video/via/ioctl.c +2 -0
@@ -25,6 +25,8 @@ int viafb_ioctl_get_viafb_info(u_long ar {struct viafb_ioctl_info viainfo; +memset (&viainfo,0 ,sizeof (struct viafb_ioctl_info )); + viainfo.viafb_id =VIAID ; viainfo.vendor_id =PCI_VIA_VENDOR_ID ;
PATCH 41/68 ACPI: disable _OSI(Windows 2009) on Asus K50IJ
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Zhang Rui <[email protected]>
commit 81074e90f5c150ca70ab8dfcc77860cbe76f364d upstream.
Fix a win7 compability issue on Asus K50IJ.
Here is the _BCM method of this laptop:
Method (_BCM, 1, NotSerialized)
{
If (LGreaterEqual (OSFG, OSVT))
{
If (LNotEqual (OSFG, OSW7))
{
Store (One, BCMD)
Store (GCBL (Arg0), Local0)
Subtract (0x0F, Local0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
Else
{
DBGR (0x0B, Zero, Zero, Arg0)
Store (Arg0, LBTN)
^^^SBRG.EC0.STBR ()
...
}
}
}LBTN is used to store the index of the brightness level in the _BCL. GCBL is a method that convert the percentage value to the index value. If _OSI(Windows 2009) is not disabled, LBTN is stored a percentage value which is surely beyond the end of _BCL package.
http://bugzilla.kernel.org/show_bug.cgi?id=14753
--- drivers/acpi/blacklist.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/acpi/blacklist.c +14 -0
@@ -185,6 +185,12 @@ static int __init dmi_disable_osi_vista(acpi_osi_setup ("!Windows 2006" );return 0 ; } +static int __init dmi_disable_osi_win7 (const struct dmi_system_id *d) +{ + printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); +acpi_osi_setup ("!Windows 2009" ); +return 0 ; +}static struct dmi_system_id acpi_osi_dmi_table[]__initdata = { {
@@ -211,6 +217,14 @@ static struct dmi_system_id acpi_osi_dmi DMI_MATCH(DMI_PRODUCT_NAME, "Sony VGN-SR290J"), }, }, + { + .callback = dmi_disable_osi_win7, + .ident = "ASUS K50IJ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "K50IJ"), + }, + },/* * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
PATCH 42/68 bnx2: Fix netpoll crash.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Benjamin Li <[email protected]>
commit 4327ba435a56ada13eedf3eb332e583c7a0586a9 upstream.
The bnx2 driver calls netif_napi_add() for all the NAPI structs during ->probe() time but not all of them will be used if we're not in MSI-X mode. This creates a problem for netpoll since it will poll all the NAPI structs in the dev_list whether or not they are scheduled, resulting in a crash when we access structure fields not initialized for that vector.
We fix it by moving the netif_napi_add() call to ->open() after the number of IRQ vectors has been determined.
--- drivers/net/bnx2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/bnx2.c +4 -2
@@ -247,6 +247,8 @@ static const struct flash_spec flash_570MODULE_DEVICE_TABLE (pci, bnx2_pci_tbl); +static void bnx2_init_napi (struct bnx2 *bp); +static inline u32 bnx2_tx_avail (struct bnx2 *bp,struct bnx2_tx_ring_info *txr) {u32 diff;
@@ -6173,6 +6175,7 @@ bnx2_open(struct net_device *dev)bnx2_disable_int (bp);bnx2_setup_int_mode (bp, disable_msi); +bnx2_init_napi (bp);bnx2_napi_enable (bp); rc =bnx2_alloc_mem (bp);if (rc)
@@ -8021,7 +8024,7 @@ bnx2_init_napi(struct bnx2 *bp) {int i; -for (i =0 ; i <BNX2_MAX_MSIX_VEC ; i++) { +for (i =0 ; i < bp->irq_nvecs; i++) {struct bnx2_napi *bnapi = &bp->bnx2_napi[i];int (*poll)(struct napi_struct *,int );
@@ -8090,7 +8093,6 @@ bnx2_init_one(struct pci_dev *pdev, cons dev->ethtool_ops = &bnx2_ethtool_ops; bp =netdev_priv (dev); -bnx2_init_napi (bp);pci_set_drvdata (pdev, dev);
PATCH 43/68 bnx2: Fix hang during rmmod bnx2.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michael Chan <[email protected]>
commit f048fa9c8686119c3858a463cab6121dced7c0bf upstream.
The regression is caused by:
commit 4327ba435a56ada13eedf3eb332e583c7a0586a9
bnx2: Fix netpoll crash.
If ->open() and ->close() are called multiple times, the same napi structs will be added to dev->napi_list multiple times, corrupting the dev->napi_list. This causes free_netdev() to hang during rmmod.
We fix this by calling netif_napi_del() during ->close().
Also, bnx2_init_napi() must not be in the __devinit section since it is called by ->open().
--- drivers/net/bnx2.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/net/bnx2.c +13 -1
@@ -248,6 +248,7 @@ static const struct flash_spec flash_570MODULE_DEVICE_TABLE (pci, bnx2_pci_tbl);static void bnx2_init_napi (struct bnx2 *bp); +static void bnx2_del_napi (struct bnx2 *bp);static inline u32 bnx2_tx_avail (struct bnx2 *bp,struct bnx2_tx_ring_info *txr) {
@@ -6237,6 +6238,7 @@ open_err:bnx2_free_skbs (bp);bnx2_free_irq (bp);bnx2_free_mem (bp); +bnx2_del_napi (bp);return rc; }
@@ -6444,6 +6446,7 @@ bnx2_close(struct net_device *dev)bnx2_free_irq (bp);bnx2_free_skbs (bp);bnx2_free_mem (bp); +bnx2_del_napi (bp); bp->link_up =0 ;netif_carrier_off (bp->dev);bnx2_set_power_state (bp, PCI_D3hot);
@@ -8019,7 +8022,16 @@ bnx2_bus_string(struct bnx2 *bp, char *sreturn str; } -static void __devinit +static void +bnx2_del_napi (struct bnx2 *bp) +{ +int i; + +for (i =0 ; i < bp->irq_nvecs; i++) +netif_napi_del (&bp->bnx2_napi[i].napi); +} + +static void bnx2_init_napi (struct bnx2 *bp) {int i;
PATCH 44/68 AT91: change dma resource index
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Nicolas Ferre <[email protected]>
commit 8d2602e0778299e2d6084f03086b716d6e7a1e1e upstream.
--- arch/arm/mach-at91/at91sam9g45_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mach-at91/at91sam9g45_devices.c +1 -1
@@ -46,7 +46,7 @@ static struct resource hdmac_resources[] .end = AT91_BASE_SYS + AT91_DMA + SZ_512 - 1, .flags = IORESOURCE_MEM, }, - [2] = { + [1] = { .start = AT91SAM9G45_ID_DMA, .end = AT91SAM9G45_ID_DMA, .flags = IORESOURCE_IRQ,
PATCH 45/68 cxgb3: fix hot plug removal crash
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Divy Le Ray <[email protected]>
commit a6f018e324ba91d0464cca6895447c2b89e6d578 upstream.
queue restart tasklets need to be stopped after napi handlers are stopped since the latter can restart them. So stop them after stopping napi.
--- drivers/net/cxgb3/cxgb3_main.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/cxgb3/cxgb3_main.c +1 -0
@@ -1274,6 +1274,7 @@ static void cxgb_down(struct adapter *adfree_irq_resources (adapter);quiesce_rx (adapter); +t3_sge_stop (adapter);flush_workqueue (cxgb3_wq);/* wait for external IRQ handler */ }
PATCH 46/68 mm: page allocator: drain per-cpu lists after direct reclaim allocation fails
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mel Gorman <[email protected]>
commit 9ee493ce0a60bf42c0f8fd0b0fe91df5704a1cbf upstream.
When under significant memory pressure, a process enters direct reclaim and immediately afterwards tries to allocate a page. If it fails and no further progress is made, it's possible the system will go OOM. However, on systems with large amounts of memory, it's possible that a significant number of pages are on per-cpu lists and inaccessible to the calling process. This leads to a process entering direct reclaim more often than it should increasing the pressure on the system and compounding the problem.
This patch notes that if direct reclaim is making progress but allocations are still failing that the system is already under heavy pressure. In this case, it drains the per-cpu lists and tries the allocation a second time before continuing.
--- mm/page_alloc.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-)
mm/page_alloc.c +16 -4
@@ -1681,6 +1681,7 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mstruct page *page =NULL ;struct reclaim_state reclaim_state;struct task_struct *p = current; +bool drained = false;cond_resched ();
@@ -1699,14 +1700,25 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mcond_resched (); -if (order !=0 ) -drain_all_pages (); +if (unlikely (!(*did_some_progress))) +return NULL ; -if (likely (*did_some_progress)) - page =get_page_from_freelist (gfp_mask, nodemask, order, +retry: + page =get_page_from_freelist (gfp_mask, nodemask, order, zonelist, high_zoneidx, alloc_flags, preferred_zone, migratetype); + +/* +* If an allocation failed after direct reclaim, it could be because +* pages are pinned on the per-cpu lists. Drain them and try again +*/ +if (!page && !drained) { +drain_all_pages (); + drained = true; + goto retry; + } +return page; }
PATCH 47/68 mm: page allocator: calculate a better estimate of NR_FREE_PAGES when memory is low and kswapd is awake
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Christoph Lameter <[email protected]>
commit aa45484031ddee09b06350ab8528bfe5b2c76d1c upstream.
Ordinarily watermark checks are based on the vmstat NR_FREE_PAGES as it is cheaper than scanning a number of lists. To avoid synchronization overhead, counter deltas are maintained on a per-cpu basis and drained both periodically and when the delta is above a threshold. On large CPU systems, the difference between the estimated and real value of NR_FREE_PAGES can be very high. If NR_FREE_PAGES is much higher than number of real free page in buddy, the VM can allocate pages below min watermark, at worst reducing the real number of pages to zero. Even if the OOM killer kills some victim for freeing memory, it may not free memory if the exit path requires a new page resulting in livelock.
This patch introduces a zone_page_state_snapshot() function (courtesy of Christoph) that takes a slightly more accurate view of an arbitrary vmstat counter. It is used to read NR_FREE_PAGES while kswapd is awake to avoid the watermark being accidentally broken. The estimate is not perfect and may result in cache line bounces but is expected to be lighter than the IPI calls necessary to continually drain the per-cpu counters while kswapd is awake.
--- include/linux/mmzone.h | 13 +++++++++++++ include/linux/vmstat.h | 22 ++++++++++++++++++++++ mm/mmzone.c | 21 +++++++++++++++++++++ mm/page_alloc.c | 4 ++-- mm/vmstat.c | 15 ++++++++++++++- 5 files changed, 72 insertions(+), 3 deletions(-)
include/linux/mmzone.h +13 -0
@@ -290,6 +290,13 @@ struct zone {unsigned long watermark[NR_WMARK ];/* +* When free pages are below this point, additional steps are taken +* when reading the number of free pages to avoid per-cpu counter +* drift allowing watermarks to be breached +*/ +unsigned long percpu_drift_mark; + +/* * We don't know if the memory that we're going to allocate will be freeable * or/and it will be released eventually, so to avoid totally wasting several * GB of ram we must reserve some of the lower zone memory (otherwise we risk
@@ -460,6 +467,12 @@ static inline int zone_is_oom_locked(conreturn test_bit (ZONE_OOM_LOCKED , &zone->flags); } +#ifdef CONFIG_SMP +unsigned long zone_nr_free_pages (struct zone *zone); +#else +#define zone_nr_free_pages (zone) zone_page_state(zone, NR_FREE_PAGES) +#endif /* CONFIG_SMP */ +/* * The "priority" of VM scanning is how much of the queues we will scan in one * go. A value of 12 for DEF_PRIORITY implies that we will scan 1/4096th of the
include/linux/vmstat.h +22 -0
@@ -166,6 +166,28 @@ static inline unsigned long zone_page_streturn x; } +/* +* More accurate version that also considers the currently pending +* deltas. For that we need to loop over all cpus to find the current +* deltas. There is no synchronization so the result cannot be +* exactly accurate either. +*/ +static inline unsigned long zone_page_state_snapshot (struct zone *zone, +enum zone_stat_item item) +{ +long x =atomic_long_read (&zone->vm_stat[item]); + +#ifdef CONFIG_SMP +int cpu; +for_each_online_cpu (cpu) + x +=zone_pcp (zone, cpu)->vm_stat_diff[item]; + +if (x <0 ) + x =0 ; +#endif +return x; +} +extern unsigned long global_reclaimable_pages (void );extern unsigned long zone_reclaimable_pages (struct zone *zone);
mm/mmzone.c +21 -0
@@ -87,3 +87,24 @@ int memmap_valid_within(unsigned long pf return 1; }#endif /* CONFIG_ARCH_HAS_HOLES_MEMORYMODEL */ + +#ifdef CONFIG_SMP +/* Called when a more accurate view of NR_FREE_PAGES is needed */ +unsigned long zone_nr_free_pages (struct zone *zone) +{ +unsigned long nr_free_pages =zone_page_state (zone,NR_FREE_PAGES ); + +/* +* While kswapd is awake, it is considered the zone is under some +* memory pressure. Under pressure, there is a risk that +* per-cpu-counter-drift will allow the min watermark to be breached +* potentially causing a live-lock. While kswapd is awake and +* free pages are low, get a better estimate for free pages +*/ +if (nr_free_pages < zone->percpu_drift_mark && + !waitqueue_active (&zone->zone_pgdat->kswapd_wait)) +return zone_page_state_snapshot (zone,NR_FREE_PAGES ); + +return nr_free_pages; +} +#endif /* CONFIG_SMP */
mm/page_alloc.c +2 -2
@@ -1365,7 +1365,7 @@ int zone_watermark_ok(struct zone *z, in {/* free_pages my go negative - that's OK */ long min = mark; -long free_pages =zone_page_state (z,NR_FREE_PAGES ) - (1 << order) +1 ; +long free_pages =zone_nr_free_pages (z) - (1 << order) +1 ;int o;if (alloc_flags &ALLOC_HIGH )
@@ -2250,7 +2250,7 @@ void show_free_areas(void)" all_unreclaimable? %s" "\n" , zone->name, -K (zone_page_state (zone,NR_FREE_PAGES )), +K (zone_nr_free_pages (zone)),K (min_wmark_pages (zone)),K (low_wmark_pages (zone)), K(high_wmark_pages(zone)),
mm/vmstat.c +14 -1
@@ -136,10 +136,23 @@ static void refresh_zone_stat_thresholdsint threshold;for_each_populated_zone (zone) { +unsigned long max_drift, tolerate_drift; + threshold =calculate_threshold (zone);for_each_online_cpu (cpu)zone_pcp (zone, cpu)->stat_threshold = threshold; + +/* +* Only set percpu_drift_mark if there is a danger that +* NR_FREE_PAGES reports the low watermark is ok when in fact +* the min watermark could be breached by an allocation +*/ + tolerate_drift =low_wmark_pages (zone) -min_wmark_pages (zone); + max_drift =num_online_cpus () * threshold; +if (max_drift > tolerate_drift) + zone->percpu_drift_mark =high_wmark_pages (zone) + + max_drift; } }
@@ -715,7 +728,7 @@ static void zoneinfo_show_print(struct s"\n scanned %lu" "\n spanned %lu" "\n present %lu" , -zone_page_state (zone,NR_FREE_PAGES ), +zone_nr_free_pages (zone),min_wmark_pages (zone),low_wmark_pages (zone), high_wmark_pages(zone),
PATCH 48/68 mm: page allocator: update free page counters after pages are placed on the free list
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Mel Gorman <[email protected]>
commit 72853e2991a2702ae93aaf889ac7db743a415dd3 upstream.
When allocating a page, the system uses NR_FREE_PAGES counters to determine if watermarks would remain intact after the allocation was made. This check is made without interrupts disabled or the zone lock held and so is race-prone by nature. Unfortunately, when pages are being freed in batch, the counters are updated before the pages are added on the list. During this window, the counters are misleading as the pages do not exist yet. When under significant pressure on systems with large numbers of CPUs, it's possible for processes to make progress even though they should have been stalled. This is particularly problematic if a number of the processes are using GFP_ATOMIC as the min watermark can be accidentally breached and in extreme cases, the system can livelock.
This patch updates the counters after the pages have been added to the list. This makes the allocator more cautious with respect to preserving the watermarks and mitigates livelock possibilities.
--- mm/page_alloc.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
mm/page_alloc.c +5 -4
@@ -531,13 +531,13 @@ static void free_pcppages_bulk(struct zo {int migratetype =0 ;int batch_free =0 ; +int to_free = count;spin_lock (&zone->lock);zone_clear_flag (zone,ZONE_ALL_UNRECLAIMABLE ); zone->pages_scanned =0 ; -__mod_zone_page_state (zone,NR_FREE_PAGES , count); -while (count) { +while (to_free) {struct page *page;struct list_head *list;
@@ -562,8 +562,9 @@ static void free_pcppages_bulk(struct zo/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */ __free_one_page (page, zone,0 ,page_private (page));trace_mm_page_pcpu_drain (page,0 ,page_private (page)); - }while (--count && --batch_free && !list_empty (list)); + }while (--to_free && --batch_free && !list_empty (list)); } +__mod_zone_page_state (zone,NR_FREE_PAGES , count);spin_unlock (&zone->lock); }
@@ -574,8 +575,8 @@ static void free_one_page(struct zone *zzone_clear_flag (zone,ZONE_ALL_UNRECLAIMABLE ); zone->pages_scanned =0 ; -__mod_zone_page_state (zone,NR_FREE_PAGES ,1 << order);__free_one_page (page, zone, order, migratetype); +__mod_zone_page_state (zone,NR_FREE_PAGES ,1 << order);spin_unlock (&zone->lock); }
PATCH 49/68 guard page for stacks that grow upwards
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Luck, Tony <[email protected]>
commit 8ca3eb08097f6839b2206e2242db4179aee3cfb3 upstream.
pa-risc and ia64 have stacks that grow upwards. Check that they do not run into other mappings. By making VM_GROWSUP 0x0 on architectures that do not ever use it, we can avoid some unpleasant #ifdefs in check_stack_guard_page().
--- include/linux/mm.h | 8 +++++++- mm/memory.c | 15 +++++++++++---- mm/mmap.c | 3 --- 3 files changed, 18 insertions(+), 8 deletions(-)
include/linux/mm.h +7 -1
@@ -77,7 +77,11 @@ extern unsigned int kobjsize(const void#define VM_MAYSHARE 0x00000080#define VM_GROWSDOWN 0x00000100/* general info on the segment */ +#if defined(CONFIG_STACK_GROWSUP ) || defined(CONFIG_IA64 )#define VM_GROWSUP 0x00000200 +#else +#define VM_GROWSUP 0x00000000 +#endif #define VM_PFNMAP 0x00000400/* Page-ranges managed without "struct page", just pure PFN */ #define VM_DENYWRITE 0x00000800/* ETXTBSY on write attempts.. */
@@ -1195,8 +1199,10 @@ unsigned long ra_submit(struct file_ra_s/* Do stack extension */ extern int expand_stack (struct vm_area_struct *vma,unsigned long address); -#ifdef CONFIG_IA64 +#if VM_GROWSUP extern int expand_upwards (struct vm_area_struct *vma,unsigned long address); +#else +#define expand_upwards (vma, address) do { } while (0)#endif extern int expand_stack_downwards (struct vm_area_struct *vma,unsigned long address);
mm/memory.c +11 -4
@@ -2630,11 +2630,9 @@ out_release: }/* -* This is like a special single-page "expand_downwards()", -* except we must first make sure that 'address-PAGE_SIZE' +* This is like a special single-page "expand_{down|up}wards()", +* except we must first make sure that 'address{-|+}PAGE_SIZE' * doesn't hit another vma. -* -* The "find_vma()" will do the right thing even if we wrap */ static inline int check_stack_guard_page (struct vm_area_struct *vma,unsigned long address) {
@@ -2653,6 +2651,15 @@ static inline int check_stack_guard_pageexpand_stack (vma, address -PAGE_SIZE ); } +if ((vma->vm_flags &VM_GROWSUP ) && address +PAGE_SIZE == vma->vm_end) { +struct vm_area_struct *next = vma->vm_next; + +/* As VM_GROWSDOWN but s/below/above/ */ +if (next && next->vm_start == address +PAGE_SIZE ) +return next->vm_flags &VM_GROWSUP ?0 : -ENOMEM ; + +expand_upwards (vma, address +PAGE_SIZE ); + }return 0 ; }
mm/mmap.c +0 -3
@@ -1600,9 +1600,6 @@ static int acct_stack_growth(struct vm_a* PA-RISC uses this for its stack; IA64 for its Register Backing Store. * vma is the last one with address > vma->vm_end. Have to extend vma. */ -#ifndef CONFIG_IA64 -static -#endif int expand_upwards (struct vm_area_struct *vma,unsigned long address) {int error;
PATCH 50/68 Fix unprotected access to task credentials in waitid()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Daniel J Blueman <[email protected]>
commit f362b73244fb16ea4ae127ced1467dd8adaa7733 upstream.
Using a program like the following:
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
id_t id;
siginfo_t infop;
pid_t res;
id = fork();
if (id == 0) { sleep(1); exit(0); }
kill(id, SIGSTOP);
alarm(1);
waitid(P_PID, id, &infop, WCONTINUED);
return 0;
}to call waitid() on a stopped process results in access to the child task's credentials without the RCU read lock being held - which may be replaced in the meantime - eliciting the following warning:
===================================================
[ INFO: suspicious rcu_dereference_check() usage. ]
---------------------------------------------------
kernel/exit.c:1460 invoked rcu_dereference_check() without protection!
other info that might help us debug this:
rcu_scheduler_active = 1, debug_locks = 1
2 locks held by waitid02/22252:
#0: (tasklist_lock){.?.?..}, at: [<ffffffff81061ce5>] do_wait+0xc5/0x310
#1: (&(&sighand->siglock)->rlock){-.-...}, at: [<ffffffff810611da>]
wait_consider_task+0x19a/0xbe0
stack backtrace:
Pid: 22252, comm: waitid02 Not tainted 2.6.35-323cd+ #3
Call Trace:
[<ffffffff81095da4>] lockdep_rcu_dereference+0xa4/0xc0
[<ffffffff81061b31>] wait_consider_task+0xaf1/0xbe0
[<ffffffff81061d15>] do_wait+0xf5/0x310
[<ffffffff810620b6>] sys_waitid+0x86/0x1f0
[<ffffffff8105fce0>] ? child_wait_callback+0x0/0x70
[<ffffffff81003282>] system_call_fastpath+0x16/0x1bThis is fixed by holding the RCU read lock in wait_task_continued() to ensure that the task's current credentials aren't destroyed between us reading the cred pointer and us reading the UID from those credentials.
Furthermore, protect wait_task_stopped() in the same way.
We don't need to keep holding the RCU read lock once we've read the UID from the credentials as holding the RCU read lock doesn't stop the target task from changing its creds under us - so the credentials may be outdated immediately after we've read the pointer, lock or no lock.
--- kernel/exit.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
kernel/exit.c +2 -3
@@ -1374,8 +1374,7 @@ static int wait_task_stopped(struct waitif (!unlikely (wo->wo_flags &WNOWAIT )) *p_code =0 ; -/* don't need the RCU readlock here as we're holding a spinlock */ - uid =__task_cred (p)->uid; + uid =task_uid (p); unlock_sig:spin_unlock_irq (&p->sighand->siglock);if (!exit_code)
@@ -1448,7 +1447,7 @@ static int wait_task_continued(struct wa }if (!unlikely (wo->wo_flags &WNOWAIT )) p->signal->flags &= ~SIGNAL_STOP_CONTINUED ; - uid =__task_cred (p)->uid; + uid =task_uid (p);spin_unlock_irq (&p->sighand->siglock); pid =task_pid_vnr (p);
PATCH 51/68 sctp: Do not reset the packet during sctp_packet_config().
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Vlad Yasevich <[email protected]>
commit 4bdab43323b459900578b200a4b8cf9713ac8fab upstream.
sctp_packet_config() is called when getting the packet ready for appending of chunks. The function should not touch the current state, since it's possible to ping-pong between two transports when sending, and that can result packet corruption followed by skb overlfow crash.
--- net/sctp/output.c | 1 - 1 file changed, 1 deletion(-)
net/sctp/output.c +0 -1
@@ -91,7 +91,6 @@ struct sctp_packet *sctp_packet_config(sSCTP_DEBUG_PRINTK ("%s: packet:%p vtag:0x%x\n" , __func__, packet, vtag); -sctp_packet_reset (packet); packet->vtag = vtag;if (ecn_capable &&sctp_packet_empty (packet)) {
PATCH 52/68 3c503: Fix IRQ probing
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit b0cf4dfb7cd21556efd9a6a67edcba0840b4d98d upstream.
The driver attempts to select an IRQ for the NIC automatically by testing which of the supported IRQs are available and then probing each available IRQ with probe_irq_{on,off}(). There are obvious race conditions here, besides which:
1. The test for availability is done by passing a NULL handler, which now always returns -EINVAL, thus the device cannot be opened:
<http://bugs.debian.org/566522>
2. probe_irq_off() will report only the first ISA IRQ handled, potentially leading to a false negative.
There was another bug that meant it ignored all error codes from request_irq() except -EBUSY, so it would 'succeed' despite this (possibly causing conflicts with other ISA devices). This was fixed by ab08999d6029bb2c79c16be5405d63d2bedbdfea 'WARNING: some request_irq() failures ignored in el2_open()', which exposed bug 1.
This patch:
1. Replaces the use of probe_irq_{on,off}() with a real interrupt handler
2. Adds a delay before checking the interrupt-seen flag
3. Disables interrupts on all failure paths
4. Distinguishes error codes from the second request_irq() call, consistently with the first
Compile-tested only.
--- drivers/net/3c503.c | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-)
drivers/net/3c503.c +30 -11
@@ -380,6 +380,12 @@ out:return retval; } +static irqreturn_t el2_probe_interrupt (int irq,void *seen) +{ + *(bool *)seen = true; +return IRQ_HANDLED ; +} +static int el2_open (struct net_device *dev) {
@@ -391,22 +397,35 @@ el2_open(struct net_device *dev)outb (EGACFR_NORM ,E33G_GACFR );/* Enable RAM and interrupts. */ do { - retval =request_irq (*irqp,NULL ,0 ,"bogus" , dev); -if (retval >=0 ) { +bool seen; + + retval =request_irq (*irqp, el2_probe_interrupt,0 , + dev->name, &seen); +if (retval == -EBUSY ) +continue ; +if (retval <0 ) + goto err_disable; +/* Twinkle the interrupt, and check if it's seen. */ -unsigned long cookie =probe_irq_on (); + seen = false; +smp_wmb ();outb_p (0x04 << ((*irqp ==9 ) ?2 : *irqp),E33G_IDCFR );outb_p (0x00 ,E33G_IDCFR ); -if (*irqp ==probe_irq_off (cookie)/* It's a good IRQ line! */ - && ((retval =request_irq (dev->irq = *irqp, - eip_interrupt,0 , dev->name, dev)) ==0 )) -break ; - }else { -if (retval != -EBUSY ) -return retval; - } +msleep (1 ); +free_irq (*irqp, el2_probe_interrupt); +if (!seen) +continue ; + + retval =request_irq (dev->irq = *irqp, eip_interrupt,0 , + dev->name, dev); +if (retval == -EBUSY ) +continue ; +if (retval <0 ) + goto err_disable; }while (*++irqp); +if (*irqp ==0 ) { + err_disable:outb (EGACFR_IRQOFF ,E33G_GACFR );/* disable interrupts. */ return -EAGAIN ; }
PATCH 53/68 asix: fix setting mac address for AX88772
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jussi Kivilinna <[email protected]>
commit 7f29a3baa825725d29db399663790d15c78cddcf upstream.
Setting new MAC address only worked when device was set to promiscuous mode. Fix MAC address by writing new address to device using undocumented command AX_CMD_READ_NODE_ID+1. Patch is tested with AX88772 device.
--- drivers/net/usb/asix.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
drivers/net/usb/asix.c +28 -2
@@ -54,6 +54,7 @@ static const char driver_name [] = "asix#define AX_CMD_WRITE_IPG0 0x12#define AX_CMD_WRITE_IPG1 0x13#define AX_CMD_READ_NODE_ID 0x13 +#define AX_CMD_WRITE_NODE_ID 0x14#define AX_CMD_WRITE_IPG2 0x14#define AX_CMD_WRITE_MULTI_FILTER 0x16#define AX88172_CMD_READ_NODE_ID 0x17
@@ -165,6 +166,7 @@ static const char driver_name [] = "asix/* This structure cannot exceed sizeof(unsigned long [5]) AKA 20 bytes */ struct asix_data {u8 multi_filter[AX_MCAST_FILTER_SIZE ]; +u8 mac_addr[ETH_ALEN ];u8 phymode;u8 ledmode;u8 eeprom_len;
@@ -728,6 +730,30 @@ static int asix_ioctl (struct net_devicereturn generic_mii_ioctl (&dev->mii,if_mii (rq), cmd,NULL ); } +static int asix_set_mac_address (struct net_device *net,void *p) +{ +struct usbnet *dev =netdev_priv (net); +struct asix_data *data = (struct asix_data *)&dev->data; +struct sockaddr *addr = p; + +if (netif_running (net)) +return -EBUSY ; +if (!is_valid_ether_addr (addr->sa_data)) +return -EADDRNOTAVAIL ; + +memcpy (net->dev_addr, addr->sa_data,ETH_ALEN ); + +/* We use the 20 byte dev->data +* for our 6 byte mac buffer +* to avoid allocating memory that +* is tricky to free later */ +memcpy (data->mac_addr, addr->sa_data,ETH_ALEN ); +asix_write_cmd_async (dev,AX_CMD_WRITE_NODE_ID ,0 ,0 ,ETH_ALEN , + data->mac_addr); + +return 0 ; +} +/* We need to override some ethtool_ops so we require our own structure so we don't interfere with other usbnet devices that may be connected at the same time. */
@@ -915,7 +941,7 @@ static const struct net_device_ops ax887 .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, .ndo_change_mtu = usbnet_change_mtu, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = asix_ioctl, .ndo_set_multicast_list = asix_set_multicast,
@@ -1208,7 +1234,7 @@ static const struct net_device_ops ax881 .ndo_stop = usbnet_stop, .ndo_start_xmit = usbnet_start_xmit, .ndo_tx_timeout = usbnet_tx_timeout, - .ndo_set_mac_address = eth_mac_addr, + .ndo_set_mac_address = asix_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_set_multicast_list = asix_set_multicast, .ndo_do_ioctl = asix_ioctl,
PATCH 54/68 dasd: use correct label location for diag fba disks
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Peter Oberparleiter <[email protected]>
commit cffab6bc5511cd6f67a60bf16b62de4267b68c4c upstream.
Partition boundary calculation fails for DASD FBA disks under the following conditions:
- disk is formatted with CMS FORMAT with a blocksize of more than 512 bytes
- all of the disk is reserved to a single CMS file using CMS RESERVE
- the disk is accessed using the DIAG mode of the DASD driver
Under these circumstances, the partition detection code tries to read the CMS label block containing partition-relevant information from logical block offset 1, while it is in fact located at physical block offset 1.
Fix this problem by using the correct CMS label block location depending on the device type as determined by the DASD SENSE ID information.
--- fs/partitions/ibm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
fs/partitions/ibm.c +12 -1
@@ -74,6 +74,7 @@ ibm_partition(struct parsed_partitions * } *label;unsigned char *data;Sector sect; +sector_t labelsect; res =0 ; blocksize =bdev_logical_block_size (bdev);
@@ -98,9 +99,19 @@ ibm_partition(struct parsed_partitions * goto out_freeall;/* +* Special case for FBA disks: label sector does not depend on +* blocksize. +*/ +if ((info->cu_type ==0x6310 && info->dev_type ==0x9336 ) || + (info->cu_type ==0x3880 && info->dev_type ==0x3370 )) + labelsect = info->label_block; +else + labelsect = info->label_block * (blocksize >>9 ); + +/* * Get volume label, extract name and type. */ - data =read_dev_sector (bdev, info->label_block*(blocksize/512 ), §); + data =read_dev_sector (bdev, labelsect, §);if (data ==NULL ) goto out_readerr;
PATCH 55/68 clocksource: sh_tmu: compute mult and shift before registration
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Aurelien Jarno <[email protected]>
commit 66f49121ffa41a19c59965b31b046d8368fec3c7 upstream.
Since commit 98962465ed9e6ea99c38e0af63fe1dcb5a79dc25 ("nohz: Prevent clocksource wrapping during idle"), the CPU of an R2D board never goes to idle. This commit assumes that mult and shift are assigned before the clocksource is registered. As a consequence the safe maximum sleep time is negative and the CPU never goes into idle.
This patch fixes the problem by moving mult and shift initialization from sh_tmu_clocksource_enable() to sh_tmu_register_clocksource().
--- drivers/clocksource/sh_tmu.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
drivers/clocksource/sh_tmu.c +11 -9
@@ -199,16 +199,8 @@ static cycle_t sh_tmu_clocksource_read(sstatic int sh_tmu_clocksource_enable (struct clocksource *cs) {struct sh_tmu_priv *p =cs_to_sh_tmu (cs); -int ret; - ret =sh_tmu_enable (p); -if (ret) -return ret; - -/* TODO: calculate good shift from rate and counter bit width */ - cs->shift =10 ; - cs->mult =clocksource_hz2mult (p->rate, cs->shift); -return 0 ; +return sh_tmu_enable (p); }static void sh_tmu_clocksource_disable (struct clocksource *cs)
@@ -228,6 +220,16 @@ static int sh_tmu_register_clocksource(s cs->disable = sh_tmu_clocksource_disable; cs->mask =CLOCKSOURCE_MASK (32 ); cs->flags =CLOCK_SOURCE_IS_CONTINUOUS ; + +/* clk_get_rate() needs an enabled clock */ +clk_enable (p->clk); +/* channel will be configured at parent clock / 4 */ + p->rate =clk_get_rate (p->clk) /4 ; +clk_disable (p->clk); +/* TODO: calculate good shift from rate and counter bit width */ + cs->shift =10 ; + cs->mult =clocksource_hz2mult (p->rate, cs->shift); +pr_info ("sh_tmu: %s used as clock source\n" , cs->name);clocksource_register (cs);return 0 ;
PATCH 56/68 gro: Fix bogus gso_size on the first fraglist entry
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
commit 622e0ca1cd4d459f5af4f2c65f4dc0dd823cb4c3 upstream.
When GRO produces fraglist entries, and the resulting skb hits an interface that is incapable of TSO but capable of FRAGLIST, we end up producing a bogus packet with gso_size non-zero.
This was reported in the field with older versions of KVM that did not set the TSO bits on tuntap.
This patch fixes that.
--- net/core/skbuff.c | 1 + 1 file changed, 1 insertion(+)
net/core/skbuff.c +1 -0
@@ -2730,6 +2730,7 @@ int skb_gro_receive(struct sk_buff **hea *NAPI_GRO_CB (nskb) = *NAPI_GRO_CB (p);skb_shinfo (nskb)->frag_list = p;skb_shinfo (nskb)->gso_size = pinfo->gso_size; + pinfo->gso_size =0 ;skb_header_release (p); nskb->prev = p;
PATCH 57/68 hostap_pci: set dev->base_addr during probe
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
commit 0f4da2d77e1bf424ac36424081afc22cbfc3ff2b upstream.
"hostap: Protect against initialization interrupt" (which reinstated "wireless: hostap, fix oops due to early probing interrupt") reintroduced Bug 16111. This is because hostap_pci wasn't setting dev->base_addr, which is now checked in prism2_interrupt. As a result, initialization was failing for PCI-based hostap devices. This corrects that oversight.
--- drivers/net/wireless/hostap/hostap_pci.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/hostap/hostap_pci.c +1 -0
@@ -329,6 +329,7 @@ static int prism2_pci_probe(struct pci_d dev->irq = pdev->irq; hw_priv->mem_start = mem; + dev->base_addr = (unsigned long ) mem;prism2_pci_cor_sreset (local);
PATCH 58/68 inotify: fix inotify oneshot support
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit ff311008ab8d2f2cfdbbefd407d1b05acc8164b2 upstream.
During the large inotify rewrite to fsnotify I completely dropped support for IN_ONESHOT. Reimplement that support.
--- fs/notify/inotify/inotify_fsnotify.c | 3 +++ 1 file changed, 3 insertions(+)
fs/notify/inotify/inotify_fsnotify.c +3 -0
@@ -72,6 +72,9 @@ static int inotify_handle_event(struct f ret =0 ; } +if (entry->mask &IN_ONESHOT ) +fsnotify_destroy_mark_by_entry (entry); +/* * If we hold the entry until after the event is on the queue * IN_IGNORED won't be able to pass this event in the queue
PATCH 59/68 Input: add compat support for sysfs and /proc capabilities output
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Dmitry Torokhov <[email protected]>
commit 15e184afa83a45cf8bafdb9dc906b97a8fbc974f upstream.
Input core displays capabilities bitmasks in form of one or more longs printed in hex form and separated by spaces. Unfortunately it does not work well for 32-bit applications running on 64-bit kernels since applications expect that number is "worth" only 32 bits when kernel advances by 64 bits.
Fix that by ensuring that output produced for compat tasks uses 32-bit units.
--- drivers/input/input.c | 84 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 70 insertions(+), 14 deletions(-)
drivers/input/input.c +70 -14
@@ -24,6 +24,7 @@#include <linux/mutex.h> #include <linux/rcupdate.h> #include <linux/smp_lock.h> +#include "input-compat.h" MODULE_AUTHOR ("Vojtech Pavlik <[email protected]>" );MODULE_DESCRIPTION ("Input core" );
@@ -758,6 +759,40 @@ static int input_attach_handler(struct ireturn error; } +#ifdef CONFIG_COMPAT + +static int input_bits_to_string (char *buf,int buf_size, +unsigned long bits,bool skip_empty) +{ +int len =0 ; + +if (INPUT_COMPAT_TEST ) { +u32 dword = bits >>32 ; +if (dword || !skip_empty) + len +=snprintf (buf, buf_size,"%x " , dword); + + dword = bits &0xffffffffUL ; +if (dword || !skip_empty || len) + len +=snprintf (buf + len,max (buf_size - len,0 ), +"%x" , dword); + }else { +if (bits || !skip_empty) + len +=snprintf (buf, buf_size,"%lx" , bits); + } + +return len; +} + +#else /* !CONFIG_COMPAT */ + +static int input_bits_to_string (char *buf,int buf_size, +unsigned long bits,bool skip_empty) +{ +return bits || !skip_empty ? +snprintf (buf, buf_size,"%lx" , bits) :0 ; +} + +#endif #ifdef CONFIG_PROC_FS
@@ -826,14 +861,25 @@ static void input_seq_print_bitmap(struc unsigned long *bitmap, int max) { int i; - -for (i =BITS_TO_LONGS (max) -1 ; i >0 ; i--) -if (bitmap[i]) -break ; +bool skip_empty = true; +char buf[18 ];seq_printf (seq,"B: %s=" , name); -for (; i >=0 ; i--) -seq_printf (seq,"%lx%s" , bitmap[i], i >0 ?" " :"" ); + +for (i =BITS_TO_LONGS (max) -1 ; i >=0 ; i--) { +if (input_bits_to_string (buf,sizeof (buf), + bitmap[i], skip_empty)) { + skip_empty = false; +seq_printf (seq,"%s%s" , buf, i >0 ?" " :"" ); + } + } + +/* +* If no output was produced print a single 0. +*/ +if (skip_empty) +seq_puts (seq,"0" ); +seq_putc (seq,'\n' ); }
@@ -1122,14 +1168,23 @@ static int input_print_bitmap(char *buf, {int i;int len =0 ; +bool skip_empty = true; -for (i =BITS_TO_LONGS (max) -1 ; i >0 ; i--) -if (bitmap[i]) -break ; +for (i =BITS_TO_LONGS (max) -1 ; i >=0 ; i--) { + len +=input_bits_to_string (buf + len,max (buf_size - len,0 ), + bitmap[i], skip_empty); +if (len) { + skip_empty = false; +if (i >0 ) + len +=snprintf (buf + len,max (buf_size - len,0 )," " ); + } + } -for (; i >=0 ; i--) - len +=snprintf (buf + len,max (buf_size - len,0 ), -"%lx%s" , bitmap[i], i >0 ?" " :"" ); +/* +* If no output was produced print a single 0. +*/ +if (len ==0 ) + len =snprintf (buf, buf_size,"%d" ,0 );if (add_cr) len +=snprintf (buf + len,max (buf_size - len,0 ),"\n" );
@@ -1144,7 +1199,8 @@ static ssize_t input_dev_show_cap_##bm(s { \struct input_dev *input_dev =to_input_dev (dev); \ int len = input_print_bitmap(buf, PAGE_SIZE, \ - input_dev->bm##bit, ev##_MAX, 1); \ + input_dev->bm##bit, ev##_MAX, \ + true); \ return min_t(int, len, PAGE_SIZE); \ } \ static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL)
@@ -1208,7 +1264,7 @@ static int input_add_uevent_bm_var(struc len =input_print_bitmap (&env->buf[env->buflen -1 ],sizeof (env->buf) - env->buflen, - bitmap, max,0 ); + bitmap, max, false);if (len >= (sizeof (env->buf) - env->buflen))return -ENOMEM ;
PATCH 60/68 MIPS: Quit using undefined behavior of ADDU in 64-bit atomic operations.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Daney <[email protected]>
commit f2a68272d799bf4092443357142f63b74f7669a1 upstream.
For 64-bit, we must use DADDU and DSUBU.
To: [email protected]
Patchwork: https://patchwork.linux-mips.org/patch/1483/
--- arch/mips/include/asm/atomic.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
arch/mips/include/asm/atomic.h +12 -12
@@ -434,7 +434,7 @@ static __inline__ void atomic64_add(long __asm__ __volatile__(" .set mips3 \n" "1: lld %0, %1 # atomic64_add \n" -" addu %0, %2 \n" +" daddu %0, %2 \n" " scd %0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n"
@@ -446,7 +446,7 @@ static __inline__ void atomic64_add(long __asm__ __volatile__(" .set mips3 \n" "1: lld %0, %1 # atomic64_add \n" -" addu %0, %2 \n" +" daddu %0, %2 \n" " scd %0, %1 \n" " beqz %0, 2f \n" " .subsection 2 \n"
@@ -479,7 +479,7 @@ static __inline__ void atomic64_sub(long __asm__ __volatile__(" .set mips3 \n" "1: lld %0, %1 # atomic64_sub \n" -" subu %0, %2 \n" +" dsubu %0, %2 \n" " scd %0, %1 \n" " beqzl %0, 1b \n" " .set mips0 \n"
@@ -491,7 +491,7 @@ static __inline__ void atomic64_sub(long __asm__ __volatile__(" .set mips3 \n" "1: lld %0, %1 # atomic64_sub \n" -" subu %0, %2 \n" +" dsubu %0, %2 \n" " scd %0, %1 \n" " beqz %0, 2f \n" " .subsection 2 \n"
@@ -524,10 +524,10 @@ static __inline__ long atomic64_add_retu __asm__ __volatile__(" .set mips3 \n" "1: lld %1, %2 # atomic64_add_return \n" -" addu %0, %1, %3 \n" +" daddu %0, %1, %3 \n" " scd %0, %2 \n" " beqzl %0, 1b \n" -" addu %0, %1, %3 \n" +" daddu %0, %1, %3 \n" " .set mips0 \n" :"=&r" (result),"=&r" (temp),"=m" (v->counter) : "Ir" (i), "m" (v->counter)
@@ -538,10 +538,10 @@ static __inline__ long atomic64_add_retu __asm__ __volatile__(" .set mips3 \n" "1: lld %1, %2 # atomic64_add_return \n" -" addu %0, %1, %3 \n" +" daddu %0, %1, %3 \n" " scd %0, %2 \n" " beqz %0, 2f \n" -" addu %0, %1, %3 \n" +" daddu %0, %1, %3 \n" " .subsection 2 \n" "2: b 1b \n" " .previous \n"
@@ -576,10 +576,10 @@ static __inline__ long atomic64_sub_retu __asm__ __volatile__(" .set mips3 \n" "1: lld %1, %2 # atomic64_sub_return \n" -" subu %0, %1, %3 \n" +" dsubu %0, %1, %3 \n" " scd %0, %2 \n" " beqzl %0, 1b \n" -" subu %0, %1, %3 \n" +" dsubu %0, %1, %3 \n" " .set mips0 \n" :"=&r" (result),"=&r" (temp),"=m" (v->counter) : "Ir" (i), "m" (v->counter)
@@ -590,10 +590,10 @@ static __inline__ long atomic64_sub_retu __asm__ __volatile__(" .set mips3 \n" "1: lld %1, %2 # atomic64_sub_return \n" -" subu %0, %1, %3 \n" +" dsubu %0, %1, %3 \n" " scd %0, %2 \n" " beqz %0, 2f \n" -" subu %0, %1, %3 \n" +" dsubu %0, %1, %3 \n" " .subsection 2 \n" "2: b 1b \n" " .previous \n"
PATCH 61/68 MIPS: Set io_map_base for several PCI bridges lacking it
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit 8faf2e6c201d95b780cd3b4674b7a55ede6dcbbb upstream.
Several MIPS platforms don't set pci_controller::io_map_base for their PCI bridges. This results in a panic in pci_iomap(). (The panic is conditional on CONFIG_PCI_DOMAINS, but that is now enabled for all PCI MIPS systems.)
Patchwork: https://patchwork.linux-mips.org/patch/1377/
--- arch/mips/mti-malta/malta-pci.c | 2 ++ arch/mips/nxp/pnx8550/common/pci.c | 1 + arch/mips/nxp/pnx8550/common/setup.c | 2 +- arch/mips/pci/ops-pmcmsp.c | 1 + arch/mips/pci/pci-yosemite.c | 1 + 5 files changed, 6 insertions(+), 1 deletion(-)
arch/mips/mti-malta/malta-pci.c +2 -0
@@ -247,6 +247,8 @@ void __init mips_pcibios_init(void) iomem_resource.end &=0xfffffffffULL ;/* 64 GB */ ioport_resource.end = controller->io_resource->end; + controller->io_map_base = mips_io_port_base; +register_pci_controller (controller); }
arch/mips/nxp/pnx8550/common/pci.c +1 -0
@@ -44,6 +44,7 @@ extern struct pci_ops pnx8550_pci_ops;static struct pci_controller pnx8550_controller = { .pci_ops = &pnx8550_pci_ops, + .io_map_base =PNX8550_PORT_BASE , .io_resource = &pci_io_resource, .mem_resource = &pci_mem_resource, };
arch/mips/nxp/pnx8550/common/setup.c +1 -1
@@ -113,7 +113,7 @@ void __init plat_mem_setup(void)PNX8550_GLB2_ENAB_INTA_O =0 ;/* IO/MEM resources. */ -set_io_port_base (KSEG1 ); +set_io_port_base (PNX8550_PORT_BASE ); ioport_resource.start =0 ; ioport_resource.end = ~0 ; iomem_resource.start =0 ;
arch/mips/pci/ops-pmcmsp.c +1 -0
@@ -944,6 +944,7 @@ static struct pci_controller msp_pci_con .pci_ops = &msp_pci_ops, .mem_resource = &pci_mem_resource, .mem_offset = 0, + .io_map_base = MSP_PCI_IOSPACE_BASE, .io_resource = &pci_io_resource, .io_offset = 0 };
arch/mips/pci/pci-yosemite.c +1 -0
@@ -54,6 +54,7 @@ static int __init pmc_yosemite_setup(voipanic (ioremap_failed);set_io_port_base (io_v_base); + py_controller.io_map_base = io_v_base;TITAN_WRITE (RM9000x2_OCD_LKM7,TITAN_READ (RM9000x2_OCD_LKM7) |1 ); ioport_resource.end =TITAN_IO_SIZE -1 ;
PATCH 62/68 MIPS: uasm: Add OR instruction.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 5808184f1b2fe06ef8a54a2b7fb1596d58098acf upstream.
This is needed for the fix of the M3 workaround.
--- arch/mips/mm/uasm.c | 4 +++- arch/mips/mm/uasm.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-)
arch/mips/mm/uasm.c +3 -1
@@ -62,7 +62,7 @@ enum opcode { insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret, insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld, insn_lui, insn_lw, insn_mfc0, - insn_mtc0, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, + insn_mtc0, insn_or, insn_ori, insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll, insn_sra, insn_srl, insn_subu, insn_sw, insn_tlbp, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori };
@@ -116,6 +116,7 @@ static struct insn insn_table[] __cpuini { insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET}, { insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET}, + { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD }, { insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM }, { insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM }, { insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
@@ -362,6 +363,7 @@ I_u2s3u1(_lw) I_u1u2u3(_mfc0) I_u1u2u3(_mtc0) I_u2u1u3(_ori) +I_u3u1u2(_or) I_u2s3u1(_pref) I_0(_rfe) I_u2s3u1(_sc)
arch/mips/mm/uasm.h +1 -0
@@ -78,6 +78,7 @@ Ip_u2s3u1(_lw);Ip_u1u2u3 (_mfc0);Ip_u1u2u3 (_mtc0);Ip_u2u1u3 (_ori); +Ip_u3u1u2 (_or);Ip_u2s3u1 (_pref);Ip_0 (_rfe);Ip_u2s3u1 (_sc);
PATCH 63/68 pata_pdc202xx_old: fix UDMA mode for Promise UDMA33 cards
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bartlomiej Zolnierkiewicz <[email protected]>
commit a75032e8772d13dab5e3501413d7e14a148281b4 upstream.
Quoted 20 lines · Russell King
Found the problem - getting rid of the read of the alt status register after the command has been written fixes the UDMA CRC errors on write:
(quoted diff) +2
-1@@ -676,7 +676,8 @@ void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf) DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command); iowrite8(tf->command, ap->ioaddr.command_addr); - ata_sff_pause(ap); + ndelay(400); +// ata_sff_pause(ap); } EXPORT_SYMBOL_GPL(ata_sff_exec_command);This rather makes sense. The PDC20247 handles the UDMA part of the protocol. It has no way to tell the PDC20246 to wait while it suspends UDMA, so that a normal register access can take place - the 246 ploughs on with the register access without any regard to the state of the 247.
Quoted 4 lines
If the drive immediately starts the UDMA protocol after a write to the command register (as it probably will for the DMA WRITE command), then we'll be accessing the taskfile in the middle of the UDMA setup, which can't be good. It's certainly a violation of the ATA specs.
Fix it by adding custom ->sff_exec_command method for UDMA33 chipsets.
--- drivers/ata/pata_pdc202xx_old.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/ata/pata_pdc202xx_old.c +12 -1
@@ -2,7 +2,7 @@* pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer * (C) 2005 Red Hat Inc * Alan Cox <[email protected]> -* (C) 2007,2009 Bartlomiej Zolnierkiewicz +* (C) 2007,2009,2010 Bartlomiej Zolnierkiewicz * * Based in part on linux/drivers/ide/pci/pdc202xx_old.c *
@@ -35,6 +35,15 @@ static int pdc2026x_cable_detect(structreturn ATA_CBL_PATA80 ; } +static void pdc20246_exec_command (struct ata_port *ap, +const struct ata_taskfile *tf) +{ +DPRINTK ("ata%u: cmd 0x%X\n" , ap->print_id, tf->command); + +iowrite8 (tf->command, ap->ioaddr.command_addr); +ndelay (400 ); +} +/** * pdc202xx_configure_piomode - set chip PIO timing * @ap: ATA interface
@@ -271,6 +280,8 @@ static struct ata_port_operations pdc202 .cable_detect = ata_cable_40wire, .set_piomode = pdc202xx_set_piomode, .set_dmamode = pdc202xx_set_dmamode, + + .sff_exec_command = pdc20246_exec_command, };static struct ata_port_operations pdc2026x_port_ops = {
PATCH 64/68 pata_pdc202xx_old: fix UDMA mode for PDC2026x chipsets
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
commit 750e519da7b3f470fe1b5b55c8d8f52d6d6371e4 upstream.
PDC2026x chipsets need the same treatment as PDC20246 one.
This is completely untested but will hopefully fix UDMA issues that people have been reporting against pata_pdc202xx_old for the last couple of years.
--- drivers/ata/pata_pdc202xx_old.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/ata/pata_pdc202xx_old.c +4 -2
@@ -35,7 +35,7 @@ static int pdc2026x_cable_detect(structreturn ATA_CBL_PATA80 ; } -static void pdc20246_exec_command (struct ata_port *ap, +static void pdc202xx_exec_command (struct ata_port *ap,const struct ata_taskfile *tf) {DPRINTK ("ata%u: cmd 0x%X\n" , ap->print_id, tf->command);
@@ -281,7 +281,7 @@ static struct ata_port_operations pdc202 .set_piomode = pdc202xx_set_piomode, .set_dmamode = pdc202xx_set_dmamode, - .sff_exec_command = pdc20246_exec_command, + .sff_exec_command = pdc202xx_exec_command, };static struct ata_port_operations pdc2026x_port_ops = {
@@ -295,6 +295,8 @@ static struct ata_port_operations pdc202 .dev_config = pdc2026x_dev_config, .port_start = pdc2026x_port_start, + + .sff_exec_command = pdc202xx_exec_command, };static int pdc202xx_init_one (struct pci_dev *dev,const struct pci_device_id *id)
PATCH 65/68 MIPS: Sibyte: Fix M3 TLB exception handler workaround.
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ralf Baechle <[email protected]>
commit 3d45285dd1ff4d4a1361b95e2d6508579a4402b5 upstream.
The M3 workaround needs to cmpare the region and VPN2 fields only.
--- arch/mips/mm/tlbex.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
arch/mips/mm/tlbex.c +16 -6
@@ -725,10 +725,15 @@ static void __cpuinit build_r4000_tlb_re* create the plain linear handler */ if (bcm1250_m3_war ()) { -UASM_i_MFC0 (&p,K0 ,C0_BADVADDR ); -UASM_i_MFC0 (&p,K1 ,C0_ENTRYHI ); +unsigned int segbits =44 ; + +uasm_i_dmfc0 (&p,K0 ,C0_BADVADDR ); +uasm_i_dmfc0 (&p,K1 ,C0_ENTRYHI );uasm_i_xor (&p,K0 ,K0 ,K1 ); -UASM_i_SRL (&p,K0 ,K0 ,PAGE_SHIFT +1 ); +uasm_i_dsrl32 (&p,K1 ,K0 ,62 -32 ); +uasm_i_dsrl (&p,K0 ,K0 ,12 +1 ); +uasm_i_dsll32 (&p,K0 ,K0 ,64 +12 +1 - segbits -32 ); +uasm_i_or (&p,K0 ,K0 ,K1 );uasm_il_bnez (&p, &r,K0 , label_leave);/* No need for uasm_i_nop */ }
@@ -1242,10 +1247,15 @@ static void __cpuinit build_r4000_tlb_lomemset (relocs,0 ,sizeof (relocs));if (bcm1250_m3_war ()) { -UASM_i_MFC0 (&p,K0 ,C0_BADVADDR ); -UASM_i_MFC0 (&p,K1 ,C0_ENTRYHI ); +unsigned int segbits =44 ; + +uasm_i_dmfc0 (&p,K0 ,C0_BADVADDR ); +uasm_i_dmfc0 (&p,K1 ,C0_ENTRYHI );uasm_i_xor (&p,K0 ,K0 ,K1 ); -UASM_i_SRL (&p,K0 ,K0 ,PAGE_SHIFT +1 ); +uasm_i_dsrl32 (&p,K1 ,K0 ,62 -32 ); +uasm_i_dsrl (&p,K0 ,K0 ,12 +1 ); +uasm_i_dsll32 (&p,K0 ,K0 ,64 +12 +1 - segbits -32 ); +uasm_i_or (&p,K0 ,K0 ,K1 );uasm_il_bnez (&p, &r,K0 , label_leave);/* No need for uasm_i_nop */ }
PATCH 66/68 sis-agp: Remove SIS 760, handled by amd64-agp
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ben Hutchings <[email protected]>
commit d831692a1a8e9ceaaa9bb16bb3fc503b7e372558 upstream.
SIS 760 is listed in the device tables for both amd64-agp and sis-agp. amd64-agp is apparently preferable since it has workarounds for some BIOS misconfigurations that sis-agp doesn't handle.
--- drivers/char/agp/sis-agp.c | 8 -------- 1 file changed, 8 deletions(-)
drivers/char/agp/sis-agp.c +0 -8
@@ -415,14 +415,6 @@ static struct pci_device_id agp_sis_pci_ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, - { - .class = (PCI_CLASS_BRIDGE_HOST << 8), - .class_mask = ~0, - .vendor = PCI_VENDOR_ID_SI, - .device = PCI_DEVICE_ID_SI_760, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { } };
PATCH 67/68 alpha: Fix printk format errors
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: Michael Cree <[email protected]>
commit 3e073367a57d41e506f20aebb98e308387ce3090 upstream.
When compiling alpha generic build get errors such as:arch/alpha/kernel/err_marvel.c: In function ‘marvel_print_err_cyc’:arch/alpha/kernel/err_marvel.c:119: error: format ‘%ld’ expects type ‘long int’, but argument 6 has type ‘u64’
Replaced a number of %ld format specifiers with %lld since u64 is unsigned long long.
--- arch/alpha/kernel/err_marvel.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/alpha/kernel/err_marvel.c +3 -3
@@ -109,7 +109,7 @@ marvel_print_err_cyc(u64 err_cyc)#define IO7__ERR_CYC__CYCLE__M (0x7) printk("%s Packet In Error: %s\n" - "%s Error in %s, cycle %ld%s%s\n", + "%s Error in %s, cycle %lld%s%s\n", err_print_prefix, packet_desc[EXTRACT(err_cyc, IO7__ERR_CYC__PACKET)], err_print_prefix,
@@ -313,7 +313,7 @@ marvel_print_po7_ugbge_sym(u64 ugbge_sym } printk("%s Up Hose Garbage Symptom:\n" - "%s Source Port: %ld - Dest PID: %ld - OpCode: %s\n", + "%s Source Port: %lld - Dest PID: %lld - OpCode: %s\n", err_print_prefix, err_print_prefix, EXTRACT(ugbge_sym, IO7__PO7_UGBGE_SYM__UPH_SRC_PORT),
@@ -552,7 +552,7 @@ marvel_print_pox_spl_cmplt(u64 spl_cmplt#define IO7__POX_SPLCMPLT__REM_BYTE_COUNT__M (0xfff) printk("%s Split Completion Error:\n" - "%s Source (Bus:Dev:Func): %ld:%ld:%ld\n", + "%s Source (Bus:Dev:Func): %lld:%lld:%lld\n", err_print_prefix, err_print_prefix, EXTRACT(spl_cmplt, IO7__POX_SPLCMPLT__SOURCE_BUS),
PATCH 68/68 x86: Add memory modify constraints to xchg() and cmpxchg()
In reply to Greg KH2.6.32-stable review patch. If anyone has any objections, please let us know.
------------------
From: H. Peter Anvin <[email protected]>
commit 113fc5a6e8c2288619ff7e8187a6f556b7e0d372 upstream.
[ Backport to .32 by Tomáš Janoušek <[email protected]> ]
xchg() and cmpxchg() modify their memory operands, not merely read them. For some versions of gcc the "memory" clobber has apparently dealt with the situation, but not for all.
LKML-Reference: <[email protected]>
--- arch/x86/include/asm/cmpxchg_32.h | 65 +++++++++++--------------------------- arch/x86/include/asm/cmpxchg_64.h | 4 -- 2 files changed, 20 insertions(+), 49 deletions(-)
arch/x86/include/asm/cmpxchg_32.h +19 -46
@@ -17,60 +17,33 @@ struct __xchg_dummy {#define __xg (x) ((struct __xchg_dummy *)(x))/* -* The semantics of XCHGCMP8B are a bit strange, this is why -* there is a loop and the loading of %%eax and %%edx has to -* be inside. This inlines well in most cases, the cached -* cost is around ~38 cycles. (in the future we might want -* to do an SIMD/3DNOW!/MMX/FPU 64-bit store here, but that -* might have an implicit FPU-save as a cost, so it's not -* clear which path to go.) +* CMPXCHG8B only writes to the target if we had the previous +* value in registers, otherwise it acts as a read and gives us the +* "new previous" value. That is why there is a loop. Preloading +* EDX:EAX is a performance optimization: in the common case it means +* we need only one locked operation. * -* cmpxchg8b must be used with the lock prefix here to allow -* the instruction to be executed atomically, see page 3-102 -* of the instruction set reference 24319102.pdf. We need -* the reader side to see the coherent 64bit value. +* A SIMD/3DNOW!/MMX/FPU 64-bit store here would require at the very +* least an FPU save and/or %cr0.ts manipulation. +* +* cmpxchg8b must be used with the lock prefix here to allow the +* instruction to be executed atomically. We need to have the reader +* side to see the coherent 64bit value. */ -static inline void __set_64bit (unsigned long long *ptr, -unsigned int low,unsigned int high) +static inline void set_64bit (volatile u64 *ptr,u64 value) { +u32 low = value; +u32 high = value >>32 ; +u64 prev = *ptr; + asmvolatile ("\n1:\t" -"movl (%1), %%eax\n\t" -"movl 4(%1), %%edx\n\t" LOCK_PREFIX "cmpxchg8b %0\n\t" "jnz 1b" - :"=m" (*ptr) - :"D" (ptr), -"b" (low), -"c" (high) - :"ax" ,"dx" ,"memory" ); -} - -static inline void __set_64bit_constant (unsigned long long *ptr, -unsigned long long value) -{ -__set_64bit (ptr, (unsigned int )value, (unsigned int )(value >>32 )); + :"=m" (*ptr),"+A" (prev) + :"b" (low),"c" (high) + :"memory" ); } -#define ll_low (x) *(((unsigned int *)&(x)) + 0) -#define ll_high (x) *(((unsigned int *)&(x)) + 1) - -static inline void __set_64bit_var (unsigned long long *ptr, -unsigned long long value) -{ -__set_64bit (ptr,ll_low (value),ll_high (value)); -} - -#define set_64bit (ptr, value) \ - (__builtin_constant_p((value)) \ - ? __set_64bit_constant((ptr), (value)) \ - : __set_64bit_var((ptr), (value))) - -#define _set_64bit (ptr, value) \ - (__builtin_constant_p(value) \ - ? __set_64bit(ptr, (unsigned int)(value), \ - (unsigned int)((value) >> 32)) \ - : __set_64bit(ptr, ll_low((value)), ll_high((value)))) -/* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway * Note 2: xchg has side effect, so that attribute volatile is necessary,
arch/x86/include/asm/cmpxchg_64.h +1 -3
@@ -8,13 +8,11 @@#define __xg (x) ((volatile long *)(x)) -static inline void set_64bit (volatile unsigned long *ptr,unsigned long val) +static inline void set_64bit (volatile u64 *ptr,u64 val) { *ptr = val; } -#define _set_64bit set_64bit -/* * Note: no "lock" prefix even on SMP: xchg always implies lock anyway * Note 2: xchg has side effect, so that attribute volatile is necessary,