cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

int.uc (3755B)


      1/* -*- linux-c -*- ------------------------------------------------------- *
      2 *
      3 *   Copyright 2002-2004 H. Peter Anvin - All Rights Reserved
      4 *
      5 *   This program is free software; you can redistribute it and/or modify
      6 *   it under the terms of the GNU General Public License as published by
      7 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
      8 *   Boston MA 02111-1307, USA; either version 2 of the License, or
      9 *   (at your option) any later version; incorporated herein by reference.
     10 *
     11 * ----------------------------------------------------------------------- */
     12
     13/*
     14 * int$#.c
     15 *
     16 * $#-way unrolled portable integer math RAID-6 instruction set
     17 *
     18 * This file is postprocessed using unroll.awk
     19 */
     20
     21#include <linux/raid/pq.h>
     22
     23/*
     24 * This is the C data type to use
     25 */
     26
     27/* Change this from BITS_PER_LONG if there is something better... */
     28#if BITS_PER_LONG == 64
     29# define NBYTES(x) ((x) * 0x0101010101010101UL)
     30# define NSIZE  8
     31# define NSHIFT 3
     32# define NSTRING "64"
     33typedef u64 unative_t;
     34#else
     35# define NBYTES(x) ((x) * 0x01010101U)
     36# define NSIZE  4
     37# define NSHIFT 2
     38# define NSTRING "32"
     39typedef u32 unative_t;
     40#endif
     41
     42
     43
     44/*
     45 * IA-64 wants insane amounts of unrolling.  On other architectures that
     46 * is just a waste of space.
     47 */
     48#if ($# <= 8) || defined(__ia64__)
     49
     50
     51/*
     52 * These sub-operations are separate inlines since they can sometimes be
     53 * specially optimized using architecture-specific hacks.
     54 */
     55
     56/*
     57 * The SHLBYTE() operation shifts each byte left by 1, *not*
     58 * rolling over into the next byte
     59 */
     60static inline __attribute_const__ unative_t SHLBYTE(unative_t v)
     61{
     62	unative_t vv;
     63
     64	vv = (v << 1) & NBYTES(0xfe);
     65	return vv;
     66}
     67
     68/*
     69 * The MASK() operation returns 0xFF in any byte for which the high
     70 * bit is 1, 0x00 for any byte for which the high bit is 0.
     71 */
     72static inline __attribute_const__ unative_t MASK(unative_t v)
     73{
     74	unative_t vv;
     75
     76	vv = v & NBYTES(0x80);
     77	vv = (vv << 1) - (vv >> 7); /* Overflow on the top bit is OK */
     78	return vv;
     79}
     80
     81
     82static void raid6_int$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
     83{
     84	u8 **dptr = (u8 **)ptrs;
     85	u8 *p, *q;
     86	int d, z, z0;
     87
     88	unative_t wd$$, wq$$, wp$$, w1$$, w2$$;
     89
     90	z0 = disks - 3;		/* Highest data disk */
     91	p = dptr[z0+1];		/* XOR parity */
     92	q = dptr[z0+2];		/* RS syndrome */
     93
     94	for ( d = 0 ; d < bytes ; d += NSIZE*$# ) {
     95		wq$$ = wp$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE];
     96		for ( z = z0-1 ; z >= 0 ; z-- ) {
     97			wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
     98			wp$$ ^= wd$$;
     99			w2$$ = MASK(wq$$);
    100			w1$$ = SHLBYTE(wq$$);
    101			w2$$ &= NBYTES(0x1d);
    102			w1$$ ^= w2$$;
    103			wq$$ = w1$$ ^ wd$$;
    104		}
    105		*(unative_t *)&p[d+NSIZE*$$] = wp$$;
    106		*(unative_t *)&q[d+NSIZE*$$] = wq$$;
    107	}
    108}
    109
    110static void raid6_int$#_xor_syndrome(int disks, int start, int stop,
    111				     size_t bytes, void **ptrs)
    112{
    113	u8 **dptr = (u8 **)ptrs;
    114	u8 *p, *q;
    115	int d, z, z0;
    116
    117	unative_t wd$$, wq$$, wp$$, w1$$, w2$$;
    118
    119	z0 = stop;		/* P/Q right side optimization */
    120	p = dptr[disks-2];	/* XOR parity */
    121	q = dptr[disks-1];	/* RS syndrome */
    122
    123	for ( d = 0 ; d < bytes ; d += NSIZE*$# ) {
    124		/* P/Q data pages */
    125		wq$$ = wp$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE];
    126		for ( z = z0-1 ; z >= start ; z-- ) {
    127			wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
    128			wp$$ ^= wd$$;
    129			w2$$ = MASK(wq$$);
    130			w1$$ = SHLBYTE(wq$$);
    131			w2$$ &= NBYTES(0x1d);
    132			w1$$ ^= w2$$;
    133			wq$$ = w1$$ ^ wd$$;
    134		}
    135		/* P/Q left side optimization */
    136		for ( z = start-1 ; z >= 0 ; z-- ) {
    137			w2$$ = MASK(wq$$);
    138			w1$$ = SHLBYTE(wq$$);
    139			w2$$ &= NBYTES(0x1d);
    140			wq$$ = w1$$ ^ w2$$;
    141		}
    142		*(unative_t *)&p[d+NSIZE*$$] ^= wp$$;
    143		*(unative_t *)&q[d+NSIZE*$$] ^= wq$$;
    144	}
    145
    146}
    147
    148const struct raid6_calls raid6_intx$# = {
    149	raid6_int$#_gen_syndrome,
    150	raid6_int$#_xor_syndrome,
    151	NULL,			/* always valid */
    152	"int" NSTRING "x$#",
    153	0
    154};
    155
    156#endif