LCOV - code coverage report
Current view: top level - arch/x86/um/asm - checksum.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 4 0.0 %
Date: 2023-04-06 08:38:28 Functions: 0 0 -

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0 */
       2             : #ifndef __UM_CHECKSUM_H
       3             : #define __UM_CHECKSUM_H
       4             : 
       5             : #include <linux/string.h>
       6             : #include <linux/in6.h>
       7             : #include <linux/uaccess.h>
       8             : 
       9             : /*
      10             :  * computes the checksum of a memory block at buff, length len,
      11             :  * and adds in "sum" (32-bit)
      12             :  *
      13             :  * returns a 32-bit number suitable for feeding into itself
      14             :  * or csum_tcpudp_magic
      15             :  *
      16             :  * this function must be called with even lengths, except
      17             :  * for the last fragment, which may be odd
      18             :  *
      19             :  * it's best to have buff aligned on a 32-bit boundary
      20             :  */
      21             : extern __wsum csum_partial(const void *buff, int len, __wsum sum);
      22             : 
      23             : /**
      24             :  * csum_fold - Fold and invert a 32bit checksum.
      25             :  * sum: 32bit unfolded sum
      26             :  *
      27             :  * Fold a 32bit running checksum to 16bit and invert it. This is usually
      28             :  * the last step before putting a checksum into a packet.
      29             :  * Make sure not to mix with 64bit checksums.
      30             :  */
      31             : static inline __sum16 csum_fold(__wsum sum)
      32             : {
      33           0 :         __asm__(
      34             :                 "  addl %1,%0\n"
      35             :                 "  adcl $0xffff,%0"
      36             :                 : "=r" (sum)
      37           0 :                 : "r" ((__force u32)sum << 16),
      38           0 :                   "0" ((__force u32)sum & 0xffff0000)
      39             :         );
      40           0 :         return (__force __sum16)(~(__force u32)sum >> 16);
      41             : }
      42             : 
      43             : /**
      44             :  * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
      45             :  * @saddr: source address
      46             :  * @daddr: destination address
      47             :  * @len: length of packet
      48             :  * @proto: ip protocol of packet
      49             :  * @sum: initial sum to be added in (32bit unfolded)
      50             :  *
      51             :  * Returns the pseudo header checksum the input data. Result is
      52             :  * 32bit unfolded.
      53             :  */
      54             : static inline __wsum
      55             : csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
      56             :                   __u8 proto, __wsum sum)
      57             : {
      58             :         asm("  addl %1, %0\n"
      59             :             "  adcl %2, %0\n"
      60             :             "  adcl %3, %0\n"
      61             :             "  adcl $0, %0\n"
      62             :                 : "=r" (sum)
      63             :             : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum));
      64             :         return sum;
      65             : }
      66             : 
      67             : /*
      68             :  * computes the checksum of the TCP/UDP pseudo-header
      69             :  * returns a 16-bit checksum, already complemented
      70             :  */
      71             : static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
      72             :                                         __u32 len, __u8 proto,
      73             :                                         __wsum sum)
      74             : {
      75             :         return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
      76             : }
      77             : 
      78             : /**
      79             :  * ip_fast_csum - Compute the IPv4 header checksum efficiently.
      80             :  * iph: ipv4 header
      81             :  * ihl: length of header / 4
      82             :  */
      83             : static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl)
      84             : {
      85             :         unsigned int sum;
      86             : 
      87             :         asm(    "  movl (%1), %0\n"
      88             :                 "  subl $4, %2\n"
      89             :                 "  jbe 2f\n"
      90             :                 "  addl 4(%1), %0\n"
      91             :                 "  adcl 8(%1), %0\n"
      92             :                 "  adcl 12(%1), %0\n"
      93             :                 "1: adcl 16(%1), %0\n"
      94             :                 "  lea 4(%1), %1\n"
      95             :                 "  decl %2\n"
      96             :                 "  jne     1b\n"
      97             :                 "  adcl $0, %0\n"
      98             :                 "  movl %0, %2\n"
      99             :                 "  shrl $16, %0\n"
     100             :                 "  addw %w2, %w0\n"
     101             :                 "  adcl $0, %0\n"
     102             :                 "  notl %0\n"
     103             :                 "2:"
     104             :         /* Since the input registers which are loaded with iph and ipl
     105             :            are modified, we must also specify them as outputs, or gcc
     106             :            will assume they contain their original values. */
     107             :         : "=r" (sum), "=r" (iph), "=r" (ihl)
     108             :         : "1" (iph), "2" (ihl)
     109             :         : "memory");
     110             :         return (__force __sum16)sum;
     111             : }
     112             : 
     113             : #ifdef CONFIG_X86_32
     114             : # include "checksum_32.h"
     115             : #else
     116             : # include "checksum_64.h"
     117             : #endif
     118             : 
     119             : #endif

Generated by: LCOV version 1.14