ARM: 7668/1: fix memset-related crashes caused by recent GCC (4.7.2) optimizations

Recent GCC versions (e.g. GCC-4.7.2) perform optimizations based on
assumptions about the implementation of memset and similar functions.
The current ARM optimized memset code does not return the value of
its first argument, as is usually expected from standard implementations.

For instance in the following function:

void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
{
	memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter));
	waiter->magic = waiter;
	INIT_LIST_HEAD(&waiter->list);
}

compiled as:

800554d0 <debug_mutex_lock_common>:
800554d0:       e92d4008        push    {r3, lr}
800554d4:       e1a00001        mov     r0, r1
800554d8:       e3a02010        mov     r2, #16 ; 0x10
800554dc:       e3a01011        mov     r1, #17 ; 0x11
800554e0:       eb04426e        bl      80165ea0 <memset>
800554e4:       e1a03000        mov     r3, r0
800554e8:       e583000c        str     r0, [r3, #12]
800554ec:       e5830000        str     r0, [r3]
800554f0:       e5830004        str     r0, [r3, #4]
800554f4:       e8bd8008        pop     {r3, pc}

GCC assumes memset returns the value of pointer 'waiter' in register r0; causing
register/memory corruptions.

This patch fixes the return value of the assembly version of memset.
It adds a 'mov' instruction and merges an additional load+store into
existing load/store instructions.
For ease of review, here is a breakdown of the patch into 4 simple steps:

Step 1
======
Perform the following substitutions:
ip -> r8, then
r0 -> ip,
and insert 'mov ip, r0' as the first statement of the function.
At this point, we have a memset() implementation returning the proper result,
but corrupting r8 on some paths (the ones that were using ip).

Step 2
======
Make sure r8 is saved and restored when (! CALGN(1)+0) == 1:

save r8:
-       str     lr, [sp, #-4]!
+       stmfd   sp!, {r8, lr}

and restore r8 on both exit paths:
-       ldmeqfd sp!, {pc}               @ Now <64 bytes to go.
+       ldmeqfd sp!, {r8, pc}           @ Now <64 bytes to go.
(...)
        tst     r2, #16
        stmneia ip!, {r1, r3, r8, lr}
-       ldr     lr, [sp], #4
+       ldmfd   sp!, {r8, lr}

Step 3
======
Make sure r8 is saved and restored when (! CALGN(1)+0) == 0:

save r8:
-       stmfd   sp!, {r4-r7, lr}
+       stmfd   sp!, {r4-r8, lr}

and restore r8 on both exit paths:
        bgt     3b
-       ldmeqfd sp!, {r4-r7, pc}
+       ldmeqfd sp!, {r4-r8, pc}
(...)
        tst     r2, #16
        stmneia ip!, {r4-r7}
-       ldmfd   sp!, {r4-r7, lr}
+       ldmfd   sp!, {r4-r8, lr}

Step 4
======
Rewrite register list "r4-r7, r8" as "r4-r8".

Signed-off-by: Ivan Djelic <ivan.djelic@parrot.com>
Reviewed-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Dirk Behme <dirk.behme@gmail.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Change-Id: Ie0c05696ed7c2e0d0a934233947e6a4b935e3405
ARM: 7670/1: fix the memset fix

Commit 455bd4c430b0 ("ARM: 7668/1: fix memset-related crashes caused by
recent GCC (4.7.2) optimizations") attempted to fix a compliance issue
with the memset return value.  However the memset itself became broken
by that patch for misaligned pointers.

This fixes the above by branching over the entry code from the
misaligned fixup code to avoid reloading the original pointer.

Also, because the function entry alignment is wrong in the Thumb mode
compilation, that fixup code is moved to the end.

While at it, the entry instructions are slightly reworked to help dual
issue pipelines.

Signed-off-by: Nicolas Pitre <nico@linaro.org>
Tested-by: Alexander Holler <holler@ahsoftware.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Change-Id: Ifdc6b0167104b42d23a72ffe5e6173f6e14c97ee
smdk4412: network: squashed commits

commit 9792f37daba788506559f99832c62b240402296c
Author: Sreeram Ramachandran <sreeram@google.com>
Date:   Tue Jul 8 11:37:03 2014 -0700

    Handle 'sk' being NULL in UID-based routing.

    Bug: 15413527
    Change-Id: If33bebb7b52c0ebfa8dac2452607bce0c2b0faa0
    Signed-off-by: Sreeram Ramachandran <sreeram@google.com>

commit 7ab80d7fd3f1e3faebb14313119700fd7416ad54
Author: Lorenzo Colitti <lorenzo@google.com>
Date:   Mon Mar 31 16:23:51 2014 +0900

    net: core: Support UID-based routing.

    This contains the following commits:

    1. 0149763 net: core: Add a UID range to fib rules.
    2. 1650474 net: core: Use the socket UID in routing lookups.
    3. 0b16771 net: ipv4: Add the UID to the route cache.
    4. ee058f1 net: core: Add a RTA_UID attribute to routes.
        This is so that userspace can do per-UID route lookups.

    Bug: 15413527
    Change-Id: I1285474c6734614d3bda6f61d88dfe89a4af7892
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>

commit a769ab7f07dcbbf29f2a8658aa5486bb6a2a66c3
Author: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date:   Fri Mar 8 02:07:16 2013 +0000

    ipv6: introdcue __ipv6_addr_needs_scope_id and ipv6_iface_scope_id helper functions

    [net-next commit b7ef213ef65256168df83ddfbb8131ed9adc10f9]

    __ipv6_addr_needs_scope_id checks if an ipv6 address needs to supply
    a 'sin6_scope_id != 0'. 'sin6_scope_id != 0' was enforced in case
    of link-local addresses. To support interface-local multicast these
    checks had to be enhanced and are now consolidated into these new helper
    functions.

    v2:
    a) migrated to struct ipv6_addr_props

    v3:
    a) reverted changes for ipv6_addr_props
    b) test for address type instead of comparing scope

    v4:
    a) unchanged

    Change-Id: Id6fc54cec61f967928e08a9eba4f857157d973a3
    Suggested-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
    Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
    Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
    Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
    Acked-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit af9b98af02a072c3eb0f3dd7d3df7242d8294e5c
Author: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date:   Mon Nov 18 07:07:45 2013 +0100

    ping: prevent NULL pointer dereference on write to msg_name

    A plain read() on a socket does set msg->msg_name to NULL. So check for
    NULL pointer first.

    [Backport of net-next cf970c002d270c36202bd5b9c2804d3097a52da0]

    Bug: 12780426
    Change-Id: I29d9cb95ef05ec76d37517e01317f4a29e60931c
    Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>

commit d66ae9bbbf35cd6e7a3d04f6946d506b3148f06b
Author: Cong Wang <amwang@redhat.com>
Date:   Sun Jun 2 22:43:52 2013 +0000

    ping: always initialize ->sin6_scope_id and ->sin6_flowinfo

    [net-next commit c26d6b46da3ee86fa8a864347331e5513ca84c2b]

    If we don't need scope id, we should initialize it to zero.
    Same for ->sin6_flowinfo.

    Change-Id: I28e4bc9593e76fc3434052182466fab4bb8ccf3a
    Cc: Lorenzo Colitti <lorenzo@google.com>
    Cc: David S. Miller <davem@davemloft.net>
    Signed-off-by: Cong Wang <amwang@redhat.com>
    Acked-by: Lorenzo Colitti <lorenzo@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit 22d188e621c143108e1207831e5817f24d0cccc0
Author: Lorenzo Colitti <lorenzo@google.com>
Date:   Thu Jul 4 00:12:40 2013 +0900

    net: ipv6: fix wrong ping_v6_sendmsg return value

    [net-next commit fbfe80c890a1dc521d0b629b870e32fcffff0da5]

    ping_v6_sendmsg currently returns 0 on success. It should return
    the number of bytes written instead.

    Bug: 9469865
    Change-Id: I82b7d3a37ba91ad24e6dbd97a4880745ce16ad31
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit b691b1c9931f86c3fc7a10208030752f205d1adf
Author: Lorenzo Colitti <lorenzo@google.com>
Date:   Thu Jul 4 00:52:49 2013 +0900

    net: ipv6: add missing lock in ping_v6_sendmsg

    [net-next commit a1bdc45580fc19e968b32ad27cd7e476a4aa58f6]

    Bug: 9469865
    Change-Id: I480f8ce95956dd8f17fbbb26dc60cc162f8ec933
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit 515b76147e907579254cd5997a4ab9e64da32268
Author: Lorenzo Colitti <lorenzo@google.com>
Date:   Wed Jan 16 22:09:49 2013 +0000

    net: ipv6: Add IPv6 support to the ping socket.

    [backport of net-next 6d0bfe22611602f36617bc7aa2ffa1bbb2f54c67]

    This adds the ability to send ICMPv6 echo requests without a
    raw socket. The equivalent ability for ICMPv4 was added in
    2011.

    Instead of having separate code paths for IPv4 and IPv6, make
    most of the code in net/ipv4/ping.c dual-stack and only add a
    few IPv6-specific bits (like the protocol definition) to a new
    net/ipv6/ping.c. Hopefully this will reduce divergence and/or
    duplication of bugs in the future.

    Caveats:

    - Setting options via ancillary data (e.g., using IPV6_PKTINFO
      to specify the outgoing interface) is not yet supported.
    - There are no separate security settings for IPv4 and IPv6;
      everything is controlled by /proc/net/ipv4/ping_group_range.
    - The proc interface does not yet display IPv6 ping sockets
      properly.

    Tested with a patched copy of ping6 and using raw socket calls.
    Compiles and works with all of CONFIG_IPV6={n,m,y}.

    Change-Id: Ia359af556021344fc7f890c21383aadf950b6498
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    [lorenzo@google.com: backported to 3.0]
    Signed-off-by: Lorenzo Colitti <lorenzo@google.com>

commit d72b1c37bab1bbdebb096421b5ef88ceec6eae8e
Author: Li Wei <lw@cn.fujitsu.com>
Date:   Thu Feb 21 00:09:54 2013 +0000

    ipv4: fix a bug in ping_err().

    [ Upstream commit b531ed61a2a2a77eeb2f7c88b49aa5ec7d9880d8 ]

    We should get 'type' and 'code' from the outer ICMP header.

    Change-Id: I9a467b4aa794127f22dbc5f802d17ae618aa0c74
    Signed-off-by: Li Wei <lw@cn.fujitsu.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

commit ead1926fc318a4c97e735a885db40e77135c0531
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date:   Mon Oct 24 03:06:21 2011 -0400

    ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT

    There is a long standing bug in linux tcp stack, about ACK messages sent
    on behalf of TIME_WAIT sockets.

    In the IP header of the ACK message, we choose to reflect TOS field of
    incoming message, and this might break some setups.

    Example of things that were broken :
      - Routing using TOS as a selector
      - Firewalls
      - Trafic classification / shaping

    We now remember in timewait structure the inet tos field and use it in
    ACK generation, and route lookup.

    Notes :
     - We still reflect incoming TOS in RST messages.
     - We could extend MuraliRaja Muniraju patch to report TOS value in
    netlink messages for TIME_WAIT sockets.
     - A patch is needed for IPv6

    Change-Id: Ic7ad8a7b858de181bfe2a789c472f84955397d4c
    Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit 47ef68bdd0ceb7113496f3325068202e5d1f3eba
Author: Eric Dumazet <eric.dumazet@gmail.com>
Date:   Wed Nov 30 19:00:53 2011 +0000

    ipv4: use a 64bit load/store in output path

    gcc compiler is smart enough to use a single load/store if we
    memcpy(dptr, sptr, 8) on x86_64, regardless of
    CONFIG_CC_OPTIMIZE_FOR_SIZE

    In IP header, daddr immediately follows saddr, this wont change in the
    future. We only need to make sure our flowi4 (saddr,daddr) fields wont
    break the rule.

    Change-Id: Iad9c8fd9121ec84c2599b013badaebba92db7c39
    Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

commit 5b7251328273e10d0d768a24f7b555d1e1f671e6
Author: Julian Anastasov <ja@ssi.bg>
Date:   Sun Aug 7 09:16:09 2011 +0000

    ipv4: route non-local sources for raw socket

    The raw sockets can provide source address for
    routing but their privileges are not considered. We
    can provide non-local source address, make sure the
    FLOWI_FLAG_ANYSRC flag is set if socket has privileges
    for this, i.e. based on hdrincl (IP_HDRINCL) and
    transparent flags.

    Change-Id: I136b161c584deac3885efbf217e959e1a829fc1d
    Signed-off-by: Julian Anastasov <ja@ssi.bg>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Change-Id: I0022e9536ee1861bf163e5bba4a86a3e94669960
Merge CM Changes