1 // SPDX-License-Identifier: GPL-2.0-only 1 2 /* 3 * Copyright (C) 2016 Intel Corporation 4 * 5 * Author: Gayatri Kammela <gayatri.kammela@in 6 * Author: Megha Dey <megha.dey@linux.intel.co 7 */ 8 9 #ifdef CONFIG_AS_AVX512 10 11 #include <linux/raid/pq.h> 12 #include "x86.h" 13 14 static int raid6_has_avx512(void) 15 { 16 return boot_cpu_has(X86_FEATURE_AVX2) 17 boot_cpu_has(X86_FEATURE_AVX) 18 boot_cpu_has(X86_FEATURE_AVX51 19 boot_cpu_has(X86_FEATURE_AVX51 20 boot_cpu_has(X86_FEATURE_AVX51 21 boot_cpu_has(X86_FEATURE_AVX51 22 } 23 24 static void raid6_2data_recov_avx512(int disks 25 int failb 26 { 27 u8 *p, *q, *dp, *dq; 28 const u8 *pbmul; /* P multiplie 29 const u8 *qmul; /* Q multiplie 30 const u8 x0f = 0x0f; 31 32 p = (u8 *)ptrs[disks-2]; 33 q = (u8 *)ptrs[disks-1]; 34 35 /* 36 * Compute syndrome with zero for the 37 * Use the dead data pages as temporar 38 * delta p and delta q 39 */ 40 41 dp = (u8 *)ptrs[faila]; 42 ptrs[faila] = (void *)raid6_empty_zero 43 ptrs[disks-2] = dp; 44 dq = (u8 *)ptrs[failb]; 45 ptrs[failb] = (void *)raid6_empty_zero 46 ptrs[disks-1] = dq; 47 48 raid6_call.gen_syndrome(disks, bytes, 49 50 /* Restore pointer table */ 51 ptrs[faila] = dp; 52 ptrs[failb] = dq; 53 ptrs[disks-2] = p; 54 ptrs[disks-1] = q; 55 56 /* Now, pick the proper data tables */ 57 pbmul = raid6_vgfmul[raid6_gfexi[failb 58 qmul = raid6_vgfmul[raid6_gfinv[raid6 59 raid6_gfexp[failb]]]; 60 61 kernel_fpu_begin(); 62 63 /* zmm0 = x0f[16] */ 64 asm volatile("vpbroadcastb %0, %%zmm7" 65 66 while (bytes) { 67 #ifdef CONFIG_X86_64 68 asm volatile("vmovdqa64 %0, %% 69 "vmovdqa64 %1, %% 70 "vmovdqa64 %2, %% 71 "vmovdqa64 %3, %% 72 "vpxorq %4, %%zmm 73 "vpxorq %5, %%zmm 74 "vpxorq %6, %%zmm 75 "vpxorq %7, %%zmm 76 : 77 : "m" (q[0]), "m" 78 "m" (p[64]), "m 79 "m" (dp[0]), "m 80 81 /* 82 * 1 = dq[0] ^ q[0] 83 * 9 = dq[64] ^ q[64] 84 * 0 = dp[0] ^ p[0] 85 * 8 = dp[64] ^ p[64] 86 */ 87 88 asm volatile("vbroadcasti64x2 89 "vbroadcasti64x2 90 : 91 : "m" (qmul[0]), 92 93 asm volatile("vpsraw $4, %%zmm 94 "vpsraw $4, %%zmm 95 "vpandq %%zmm7, % 96 "vpandq %%zmm7, % 97 "vpandq %%zmm7, % 98 "vpandq %%zmm7, % 99 "vpshufb %%zmm9, 100 "vpshufb %%zmm1, 101 "vpshufb %%zmm12, 102 "vpshufb %%zmm3, 103 "vpxorq %%zmm14, 104 "vpxorq %%zmm4, % 105 : 106 : ); 107 108 /* 109 * 5 = qx[0] 110 * 15 = qx[64] 111 */ 112 113 asm volatile("vbroadcasti64x2 114 "vbroadcasti64x2 115 "vpsraw $4, %%zmm 116 "vpsraw $4, %%zmm 117 "vpandq %%zmm7, % 118 "vpandq %%zmm7, % 119 "vpandq %%zmm7, % 120 "vpandq %%zmm7, % 121 "vpshufb %%zmm14, 122 "vpshufb %%zmm3, 123 "vpshufb %%zmm6, 124 "vpshufb %%zmm2, 125 "vpxorq %%zmm4, % 126 "vpxorq %%zmm12, 127 : 128 : "m" (pbmul[0]), 129 130 /* 131 * 1 = pbmul[px[0]] 132 * 13 = pbmul[px[64]] 133 */ 134 asm volatile("vpxorq %%zmm5, % 135 "vpxorq %%zmm15, 136 : 137 : ); 138 139 /* 140 * 1 = db = DQ 141 * 13 = db[64] = DQ[64] 142 */ 143 asm volatile("vmovdqa64 %%zmm1 144 "vmovdqa64 %%zmm1 145 "vpxorq %%zmm1, % 146 "vpxorq %%zmm13, 147 : 148 : "m" (dq[0]), "m 149 150 asm volatile("vmovdqa64 %%zmm0 151 "vmovdqa64 %%zmm8 152 : 153 : "m" (dp[0]), "m 154 155 bytes -= 128; 156 p += 128; 157 q += 128; 158 dp += 128; 159 dq += 128; 160 #else 161 asm volatile("vmovdqa64 %0, %% 162 "vmovdqa64 %1, %% 163 "vpxorq %2, %%zmm 164 "vpxorq %3, %%zmm 165 : 166 : "m" (*q), "m" ( 167 168 /* 1 = dq ^ q; 0 = dp ^ p */ 169 170 asm volatile("vbroadcasti64x2 171 "vbroadcasti64x2 172 : 173 : "m" (qmul[0]), 174 175 /* 176 * 1 = dq ^ q 177 * 3 = dq ^ p >> 4 178 */ 179 asm volatile("vpsraw $4, %%zmm 180 "vpandq %%zmm7, % 181 "vpandq %%zmm7, % 182 "vpshufb %%zmm1, 183 "vpshufb %%zmm3, 184 "vpxorq %%zmm4, % 185 : 186 : ); 187 188 /* 5 = qx */ 189 190 asm volatile("vbroadcasti64x2 191 "vbroadcasti64x2 192 : 193 : "m" (pbmul[0]), 194 195 asm volatile("vpsraw $4, %%zmm 196 "vpandq %%zmm7, % 197 "vpandq %%zmm7, % 198 "vpshufb %%zmm3, 199 "vpshufb %%zmm2, 200 "vpxorq %%zmm4, % 201 : 202 : ); 203 204 /* 1 = pbmul[px] */ 205 asm volatile("vpxorq %%zmm5, % 206 /* 1 = db = DQ */ 207 "vmovdqa64 %%zmm1 208 : 209 : "m" (dq[0])); 210 211 asm volatile("vpxorq %%zmm1, % 212 "vmovdqa64 %%zmm0 213 : 214 : "m" (dp[0])); 215 216 bytes -= 64; 217 p += 64; 218 q += 64; 219 dp += 64; 220 dq += 64; 221 #endif 222 } 223 224 kernel_fpu_end(); 225 } 226 227 static void raid6_datap_recov_avx512(int disks 228 void **pt 229 { 230 u8 *p, *q, *dq; 231 const u8 *qmul; /* Q multiplie 232 const u8 x0f = 0x0f; 233 234 p = (u8 *)ptrs[disks-2]; 235 q = (u8 *)ptrs[disks-1]; 236 237 /* 238 * Compute syndrome with zero for the 239 * Use the dead data page as temporary 240 */ 241 242 dq = (u8 *)ptrs[faila]; 243 ptrs[faila] = (void *)raid6_empty_zero 244 ptrs[disks-1] = dq; 245 246 raid6_call.gen_syndrome(disks, bytes, 247 248 /* Restore pointer table */ 249 ptrs[faila] = dq; 250 ptrs[disks-1] = q; 251 252 /* Now, pick the proper data tables */ 253 qmul = raid6_vgfmul[raid6_gfinv[raid6 254 255 kernel_fpu_begin(); 256 257 asm volatile("vpbroadcastb %0, %%zmm7" 258 259 while (bytes) { 260 #ifdef CONFIG_X86_64 261 asm volatile("vmovdqa64 %0, %% 262 "vmovdqa64 %1, %% 263 "vpxorq %2, %%zmm 264 "vpxorq %3, %%zmm 265 : 266 : "m" (dq[0]), "m 267 "m" (q[64])); 268 269 /* 270 * 3 = q[0] ^ dq[0] 271 * 8 = q[64] ^ dq[64] 272 */ 273 asm volatile("vbroadcasti64x2 274 "vmovapd %%zmm0, 275 "vbroadcasti64x2 276 "vmovapd %%zmm1, 277 : 278 : "m" (qmul[0]), 279 280 asm volatile("vpsraw $4, %%zmm 281 "vpsraw $4, %%zmm 282 "vpandq %%zmm7, % 283 "vpandq %%zmm7, % 284 "vpandq %%zmm7, % 285 "vpandq %%zmm7, % 286 "vpshufb %%zmm3, 287 "vpshufb %%zmm8, 288 "vpshufb %%zmm6, 289 "vpshufb %%zmm12, 290 "vpxorq %%zmm0, % 291 "vpxorq %%zmm13, 292 : 293 : ); 294 295 /* 296 * 1 = qmul[q[0] ^ dq[0]] 297 * 14 = qmul[q[64] ^ dq[64]] 298 */ 299 asm volatile("vmovdqa64 %0, %% 300 "vmovdqa64 %1, %% 301 "vpxorq %%zmm1, % 302 "vpxorq %%zmm14, 303 : 304 : "m" (p[0]), "m" 305 306 /* 307 * 2 = p[0] ^ qmul[q[0] ^ d 308 * 12 = p[64] ^ qmul[q[64] ^ d 309 */ 310 311 asm volatile("vmovdqa64 %%zmm1 312 "vmovdqa64 %%zmm1 313 "vmovdqa64 %%zmm2 314 "vmovdqa64 %%zmm1 315 : 316 : "m" (dq[0]), "m 317 "m" (p[64])); 318 319 bytes -= 128; 320 p += 128; 321 q += 128; 322 dq += 128; 323 #else 324 asm volatile("vmovdqa64 %0, %% 325 "vpxorq %1, %%zmm 326 : 327 : "m" (dq[0]), "m 328 329 /* 3 = q ^ dq */ 330 331 asm volatile("vbroadcasti64x2 332 "vbroadcasti64x2 333 : 334 : "m" (qmul[0]), 335 336 asm volatile("vpsraw $4, %%zmm 337 "vpandq %%zmm7, % 338 "vpandq %%zmm7, % 339 "vpshufb %%zmm3, 340 "vpshufb %%zmm6, 341 "vpxorq %%zmm0, % 342 : 343 : ); 344 345 /* 1 = qmul[q ^ dq] */ 346 347 asm volatile("vmovdqa64 %0, %% 348 "vpxorq %%zmm1, % 349 : 350 : "m" (p[0])); 351 352 /* 2 = p ^ qmul[q ^ dq] */ 353 354 asm volatile("vmovdqa64 %%zmm1 355 "vmovdqa64 %%zmm2 356 : 357 : "m" (dq[0]), "m 358 359 bytes -= 64; 360 p += 64; 361 q += 64; 362 dq += 64; 363 #endif 364 } 365 366 kernel_fpu_end(); 367 } 368 369 const struct raid6_recov_calls raid6_recov_avx 370 .data2 = raid6_2data_recov_avx512, 371 .datap = raid6_datap_recov_avx512, 372 .valid = raid6_has_avx512, 373 #ifdef CONFIG_X86_64 374 .name = "avx512x2", 375 #else 376 .name = "avx512x1", 377 #endif 378 .priority = 3, 379 }; 380 381 #else 382 #warning "your version of binutils lacks AVX51 383 #endif 384
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.