1 // SPDX-License-Identifier: GPL-2.0 1 2 /* 3 * In-kernel vector facility support functions 4 * 5 * Copyright IBM Corp. 2015 6 * Author(s): Hendrik Brueckner <brueckner@lin 7 */ 8 #include <linux/kernel.h> 9 #include <linux/cpu.h> 10 #include <linux/sched.h> 11 #include <asm/fpu.h> 12 13 void __kernel_fpu_begin(struct kernel_fpu *sta 14 { 15 __vector128 *vxrs = state->vxrs; 16 int mask; 17 18 /* 19 * Limit the save to the FPU/vector re 20 * in use by the previous context. 21 */ 22 flags &= state->hdr.mask; 23 if (flags & KERNEL_FPC) 24 fpu_stfpc(&state->hdr.fpc); 25 if (!cpu_has_vx()) { 26 if (flags & KERNEL_VXR_LOW) 27 save_fp_regs_vx(vxrs); 28 return; 29 } 30 mask = flags & KERNEL_VXR; 31 if (mask == KERNEL_VXR) { 32 vxrs += fpu_vstm(0, 15, vxrs); 33 vxrs += fpu_vstm(16, 31, vxrs) 34 return; 35 } 36 if (mask == KERNEL_VXR_MID) { 37 vxrs += fpu_vstm(8, 23, vxrs); 38 return; 39 } 40 mask = flags & KERNEL_VXR_LOW; 41 if (mask) { 42 if (mask == KERNEL_VXR_LOW) 43 vxrs += fpu_vstm(0, 15 44 else if (mask == KERNEL_VXR_V0 45 vxrs += fpu_vstm(0, 7, 46 else 47 vxrs += fpu_vstm(8, 15 48 } 49 mask = flags & KERNEL_VXR_HIGH; 50 if (mask) { 51 if (mask == KERNEL_VXR_HIGH) 52 vxrs += fpu_vstm(16, 3 53 else if (mask == KERNEL_VXR_V1 54 vxrs += fpu_vstm(16, 2 55 else 56 vxrs += fpu_vstm(24, 3 57 } 58 } 59 EXPORT_SYMBOL(__kernel_fpu_begin); 60 61 void __kernel_fpu_end(struct kernel_fpu *state 62 { 63 __vector128 *vxrs = state->vxrs; 64 int mask; 65 66 /* 67 * Limit the restore to the FPU/vector 68 * previous context that have been ove 69 * current context. 70 */ 71 flags &= state->hdr.mask; 72 if (flags & KERNEL_FPC) 73 fpu_lfpc(&state->hdr.fpc); 74 if (!cpu_has_vx()) { 75 if (flags & KERNEL_VXR_LOW) 76 load_fp_regs_vx(vxrs); 77 return; 78 } 79 mask = flags & KERNEL_VXR; 80 if (mask == KERNEL_VXR) { 81 vxrs += fpu_vlm(0, 15, vxrs); 82 vxrs += fpu_vlm(16, 31, vxrs); 83 return; 84 } 85 if (mask == KERNEL_VXR_MID) { 86 vxrs += fpu_vlm(8, 23, vxrs); 87 return; 88 } 89 mask = flags & KERNEL_VXR_LOW; 90 if (mask) { 91 if (mask == KERNEL_VXR_LOW) 92 vxrs += fpu_vlm(0, 15, 93 else if (mask == KERNEL_VXR_V0 94 vxrs += fpu_vlm(0, 7, 95 else 96 vxrs += fpu_vlm(8, 15, 97 } 98 mask = flags & KERNEL_VXR_HIGH; 99 if (mask) { 100 if (mask == KERNEL_VXR_HIGH) 101 vxrs += fpu_vlm(16, 31 102 else if (mask == KERNEL_VXR_V1 103 vxrs += fpu_vlm(16, 23 104 else 105 vxrs += fpu_vlm(24, 31 106 } 107 } 108 EXPORT_SYMBOL(__kernel_fpu_end); 109 110 void load_fpu_state(struct fpu *state, int fla 111 { 112 __vector128 *vxrs = &state->vxrs[0]; 113 int mask; 114 115 if (flags & KERNEL_FPC) 116 fpu_lfpc_safe(&state->fpc); 117 if (!cpu_has_vx()) { 118 if (flags & KERNEL_VXR_V0V7) 119 load_fp_regs_vx(state- 120 return; 121 } 122 mask = flags & KERNEL_VXR; 123 if (mask == KERNEL_VXR) { 124 fpu_vlm(0, 15, &vxrs[0]); 125 fpu_vlm(16, 31, &vxrs[16]); 126 return; 127 } 128 if (mask == KERNEL_VXR_MID) { 129 fpu_vlm(8, 23, &vxrs[8]); 130 return; 131 } 132 mask = flags & KERNEL_VXR_LOW; 133 if (mask) { 134 if (mask == KERNEL_VXR_LOW) 135 fpu_vlm(0, 15, &vxrs[0 136 else if (mask == KERNEL_VXR_V0 137 fpu_vlm(0, 7, &vxrs[0] 138 else 139 fpu_vlm(8, 15, &vxrs[8 140 } 141 mask = flags & KERNEL_VXR_HIGH; 142 if (mask) { 143 if (mask == KERNEL_VXR_HIGH) 144 fpu_vlm(16, 31, &vxrs[ 145 else if (mask == KERNEL_VXR_V1 146 fpu_vlm(16, 23, &vxrs[ 147 else 148 fpu_vlm(24, 31, &vxrs[ 149 } 150 } 151 152 void save_fpu_state(struct fpu *state, int fla 153 { 154 __vector128 *vxrs = &state->vxrs[0]; 155 int mask; 156 157 if (flags & KERNEL_FPC) 158 fpu_stfpc(&state->fpc); 159 if (!cpu_has_vx()) { 160 if (flags & KERNEL_VXR_LOW) 161 save_fp_regs_vx(state- 162 return; 163 } 164 mask = flags & KERNEL_VXR; 165 if (mask == KERNEL_VXR) { 166 fpu_vstm(0, 15, &vxrs[0]); 167 fpu_vstm(16, 31, &vxrs[16]); 168 return; 169 } 170 if (mask == KERNEL_VXR_MID) { 171 fpu_vstm(8, 23, &vxrs[8]); 172 return; 173 } 174 mask = flags & KERNEL_VXR_LOW; 175 if (mask) { 176 if (mask == KERNEL_VXR_LOW) 177 fpu_vstm(0, 15, &vxrs[ 178 else if (mask == KERNEL_VXR_V0 179 fpu_vstm(0, 7, &vxrs[0 180 else 181 fpu_vstm(8, 15, &vxrs[ 182 } 183 mask = flags & KERNEL_VXR_HIGH; 184 if (mask) { 185 if (mask == KERNEL_VXR_HIGH) 186 fpu_vstm(16, 31, &vxrs 187 else if (mask == KERNEL_VXR_V1 188 fpu_vstm(16, 23, &vxrs 189 else 190 fpu_vstm(24, 31, &vxrs 191 } 192 } 193 EXPORT_SYMBOL(save_fpu_state); 194
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.