1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2012 Intel Corporation 4 * Copyright (C) 2017 Linaro Ltd. <ard.biesheuvel@linaro.org> 5 */ 6 7 #include <linux/mm.h> 8 #include <linux/raid/pq.h> 9 #include <asm/simd.h> 10 #include "algos.h" 11 #include "arm/neon.h" 12 13 static void raid6_2data_recov_neon(int disks, size_t bytes, int faila, 14 int failb, void **ptrs) 15 { 16 u8 *p, *q, *dp, *dq; 17 const u8 *pbmul; /* P multiplier table for B data */ 18 const u8 *qmul; /* Q multiplier table (for both) */ 19 20 p = (u8 *)ptrs[disks - 2]; 21 q = (u8 *)ptrs[disks - 1]; 22 23 /* 24 * Compute syndrome with zero for the missing data pages 25 * Use the dead data pages as temporary storage for 26 * delta p and delta q 27 */ 28 dp = (u8 *)ptrs[faila]; 29 ptrs[faila] = page_address(ZERO_PAGE(0)); 30 ptrs[disks - 2] = dp; 31 dq = (u8 *)ptrs[failb]; 32 ptrs[failb] = page_address(ZERO_PAGE(0)); 33 ptrs[disks - 1] = dq; 34 35 raid6_gen_syndrome(disks, bytes, ptrs); 36 37 /* Restore pointer table */ 38 ptrs[faila] = dp; 39 ptrs[failb] = dq; 40 ptrs[disks - 2] = p; 41 ptrs[disks - 1] = q; 42 43 /* Now, pick the proper data tables */ 44 pbmul = raid6_vgfmul[raid6_gfexi[failb-faila]]; 45 qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila] ^ 46 raid6_gfexp[failb]]]; 47 48 scoped_ksimd() 49 __raid6_2data_recov_neon(bytes, p, q, dp, dq, pbmul, qmul); 50 } 51 52 static void raid6_datap_recov_neon(int disks, size_t bytes, int faila, 53 void **ptrs) 54 { 55 u8 *p, *q, *dq; 56 const u8 *qmul; /* Q multiplier table */ 57 58 p = (u8 *)ptrs[disks - 2]; 59 q = (u8 *)ptrs[disks - 1]; 60 61 /* 62 * Compute syndrome with zero for the missing data page 63 * Use the dead data page as temporary storage for delta q 64 */ 65 dq = (u8 *)ptrs[faila]; 66 ptrs[faila] = page_address(ZERO_PAGE(0)); 67 ptrs[disks - 1] = dq; 68 69 raid6_gen_syndrome(disks, bytes, ptrs); 70 71 /* Restore pointer table */ 72 ptrs[faila] = dq; 73 ptrs[disks - 1] = q; 74 75 /* Now, pick the proper data tables */ 76 qmul = raid6_vgfmul[raid6_gfinv[raid6_gfexp[faila]]]; 77 78 scoped_ksimd() 79 __raid6_datap_recov_neon(bytes, p, q, dq, qmul); 80 } 81 82 const struct raid6_recov_calls raid6_recov_neon = { 83 .data2 = raid6_2data_recov_neon, 84 .datap = raid6_datap_recov_neon, 85 .name = "neon", 86 }; 87