.. | .. |
---|
1125 | 1125 | } |
---|
1126 | 1126 | } |
---|
1127 | 1127 | |
---|
1128 | | -static void emulator_get_fpu(void) |
---|
| 1128 | +static unsigned long emulator_get_fpu(void) |
---|
1129 | 1129 | { |
---|
1130 | | - fpregs_lock(); |
---|
| 1130 | + unsigned long flags = fpregs_lock(); |
---|
1131 | 1131 | |
---|
1132 | 1132 | fpregs_assert_state_consistent(); |
---|
1133 | 1133 | if (test_thread_flag(TIF_NEED_FPU_LOAD)) |
---|
1134 | 1134 | switch_fpu_return(); |
---|
| 1135 | + |
---|
| 1136 | + return flags; |
---|
1135 | 1137 | } |
---|
1136 | 1138 | |
---|
1137 | | -static void emulator_put_fpu(void) |
---|
| 1139 | +static void emulator_put_fpu(unsigned long flags) |
---|
1138 | 1140 | { |
---|
1139 | | - fpregs_unlock(); |
---|
| 1141 | + fpregs_unlock(flags); |
---|
1140 | 1142 | } |
---|
1141 | 1143 | |
---|
1142 | 1144 | static void read_sse_reg(sse128_t *data, int reg) |
---|
1143 | 1145 | { |
---|
1144 | | - emulator_get_fpu(); |
---|
| 1146 | + unsigned long flags; |
---|
| 1147 | + |
---|
| 1148 | + flags = emulator_get_fpu(); |
---|
1145 | 1149 | switch (reg) { |
---|
1146 | 1150 | case 0: asm("movdqa %%xmm0, %0" : "=m"(*data)); break; |
---|
1147 | 1151 | case 1: asm("movdqa %%xmm1, %0" : "=m"(*data)); break; |
---|
.. | .. |
---|
1163 | 1167 | #endif |
---|
1164 | 1168 | default: BUG(); |
---|
1165 | 1169 | } |
---|
1166 | | - emulator_put_fpu(); |
---|
| 1170 | + emulator_put_fpu(flags); |
---|
1167 | 1171 | } |
---|
1168 | 1172 | |
---|
1169 | 1173 | static void write_sse_reg(sse128_t *data, int reg) |
---|
1170 | 1174 | { |
---|
1171 | | - emulator_get_fpu(); |
---|
| 1175 | + unsigned long flags; |
---|
| 1176 | + |
---|
| 1177 | + flags = emulator_get_fpu(); |
---|
1172 | 1178 | switch (reg) { |
---|
1173 | 1179 | case 0: asm("movdqa %0, %%xmm0" : : "m"(*data)); break; |
---|
1174 | 1180 | case 1: asm("movdqa %0, %%xmm1" : : "m"(*data)); break; |
---|
.. | .. |
---|
1190 | 1196 | #endif |
---|
1191 | 1197 | default: BUG(); |
---|
1192 | 1198 | } |
---|
1193 | | - emulator_put_fpu(); |
---|
| 1199 | + emulator_put_fpu(flags); |
---|
1194 | 1200 | } |
---|
1195 | 1201 | |
---|
1196 | 1202 | static void read_mmx_reg(u64 *data, int reg) |
---|
1197 | 1203 | { |
---|
1198 | | - emulator_get_fpu(); |
---|
| 1204 | + unsigned long flags; |
---|
| 1205 | + |
---|
| 1206 | + flags = emulator_get_fpu(); |
---|
1199 | 1207 | switch (reg) { |
---|
1200 | 1208 | case 0: asm("movq %%mm0, %0" : "=m"(*data)); break; |
---|
1201 | 1209 | case 1: asm("movq %%mm1, %0" : "=m"(*data)); break; |
---|
.. | .. |
---|
1207 | 1215 | case 7: asm("movq %%mm7, %0" : "=m"(*data)); break; |
---|
1208 | 1216 | default: BUG(); |
---|
1209 | 1217 | } |
---|
1210 | | - emulator_put_fpu(); |
---|
| 1218 | + emulator_put_fpu(flags); |
---|
1211 | 1219 | } |
---|
1212 | 1220 | |
---|
1213 | 1221 | static void write_mmx_reg(u64 *data, int reg) |
---|
1214 | 1222 | { |
---|
1215 | | - emulator_get_fpu(); |
---|
| 1223 | + unsigned long flags; |
---|
| 1224 | + |
---|
| 1225 | + flags = emulator_get_fpu(); |
---|
1216 | 1226 | switch (reg) { |
---|
1217 | 1227 | case 0: asm("movq %0, %%mm0" : : "m"(*data)); break; |
---|
1218 | 1228 | case 1: asm("movq %0, %%mm1" : : "m"(*data)); break; |
---|
.. | .. |
---|
1224 | 1234 | case 7: asm("movq %0, %%mm7" : : "m"(*data)); break; |
---|
1225 | 1235 | default: BUG(); |
---|
1226 | 1236 | } |
---|
1227 | | - emulator_put_fpu(); |
---|
| 1237 | + emulator_put_fpu(flags); |
---|
1228 | 1238 | } |
---|
1229 | 1239 | |
---|
1230 | 1240 | static int em_fninit(struct x86_emulate_ctxt *ctxt) |
---|
1231 | 1241 | { |
---|
| 1242 | + unsigned long flags; |
---|
| 1243 | + |
---|
1232 | 1244 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
---|
1233 | 1245 | return emulate_nm(ctxt); |
---|
1234 | 1246 | |
---|
1235 | | - emulator_get_fpu(); |
---|
| 1247 | + flags = emulator_get_fpu(); |
---|
1236 | 1248 | asm volatile("fninit"); |
---|
1237 | | - emulator_put_fpu(); |
---|
| 1249 | + emulator_put_fpu(flags); |
---|
1238 | 1250 | return X86EMUL_CONTINUE; |
---|
1239 | 1251 | } |
---|
1240 | 1252 | |
---|
1241 | 1253 | static int em_fnstcw(struct x86_emulate_ctxt *ctxt) |
---|
1242 | 1254 | { |
---|
| 1255 | + unsigned long flags; |
---|
1243 | 1256 | u16 fcw; |
---|
1244 | 1257 | |
---|
1245 | 1258 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
---|
1246 | 1259 | return emulate_nm(ctxt); |
---|
1247 | 1260 | |
---|
1248 | | - emulator_get_fpu(); |
---|
| 1261 | + flags = emulator_get_fpu(); |
---|
1249 | 1262 | asm volatile("fnstcw %0": "+m"(fcw)); |
---|
1250 | | - emulator_put_fpu(); |
---|
| 1263 | + emulator_put_fpu(flags); |
---|
1251 | 1264 | |
---|
1252 | 1265 | ctxt->dst.val = fcw; |
---|
1253 | 1266 | |
---|
.. | .. |
---|
1256 | 1269 | |
---|
1257 | 1270 | static int em_fnstsw(struct x86_emulate_ctxt *ctxt) |
---|
1258 | 1271 | { |
---|
| 1272 | + unsigned long flags; |
---|
1259 | 1273 | u16 fsw; |
---|
1260 | 1274 | |
---|
1261 | 1275 | if (ctxt->ops->get_cr(ctxt, 0) & (X86_CR0_TS | X86_CR0_EM)) |
---|
1262 | 1276 | return emulate_nm(ctxt); |
---|
1263 | 1277 | |
---|
1264 | | - emulator_get_fpu(); |
---|
| 1278 | + flags = emulator_get_fpu(); |
---|
1265 | 1279 | asm volatile("fnstsw %0": "+m"(fsw)); |
---|
1266 | | - emulator_put_fpu(); |
---|
| 1280 | + emulator_put_fpu(flags); |
---|
1267 | 1281 | |
---|
1268 | 1282 | ctxt->dst.val = fsw; |
---|
1269 | 1283 | |
---|
.. | .. |
---|
4182 | 4196 | static int em_fxsave(struct x86_emulate_ctxt *ctxt) |
---|
4183 | 4197 | { |
---|
4184 | 4198 | struct fxregs_state fx_state; |
---|
| 4199 | + unsigned long flags; |
---|
4185 | 4200 | int rc; |
---|
4186 | 4201 | |
---|
4187 | 4202 | rc = check_fxsr(ctxt); |
---|
4188 | 4203 | if (rc != X86EMUL_CONTINUE) |
---|
4189 | 4204 | return rc; |
---|
4190 | 4205 | |
---|
4191 | | - emulator_get_fpu(); |
---|
| 4206 | + flags = emulator_get_fpu(); |
---|
4192 | 4207 | |
---|
4193 | 4208 | rc = asm_safe("fxsave %[fx]", , [fx] "+m"(fx_state)); |
---|
4194 | 4209 | |
---|
4195 | | - emulator_put_fpu(); |
---|
| 4210 | + emulator_put_fpu(flags); |
---|
4196 | 4211 | |
---|
4197 | 4212 | if (rc != X86EMUL_CONTINUE) |
---|
4198 | 4213 | return rc; |
---|
.. | .. |
---|
4224 | 4239 | static int em_fxrstor(struct x86_emulate_ctxt *ctxt) |
---|
4225 | 4240 | { |
---|
4226 | 4241 | struct fxregs_state fx_state; |
---|
| 4242 | + unsigned long flags; |
---|
4227 | 4243 | int rc; |
---|
4228 | 4244 | size_t size; |
---|
4229 | 4245 | |
---|
.. | .. |
---|
4236 | 4252 | if (rc != X86EMUL_CONTINUE) |
---|
4237 | 4253 | return rc; |
---|
4238 | 4254 | |
---|
4239 | | - emulator_get_fpu(); |
---|
| 4255 | + flags = emulator_get_fpu(); |
---|
4240 | 4256 | |
---|
4241 | 4257 | if (size < __fxstate_size(16)) { |
---|
4242 | 4258 | rc = fxregs_fixup(&fx_state, size); |
---|
.. | .. |
---|
4253 | 4269 | rc = asm_safe("fxrstor %[fx]", : [fx] "m"(fx_state)); |
---|
4254 | 4270 | |
---|
4255 | 4271 | out: |
---|
4256 | | - emulator_put_fpu(); |
---|
| 4272 | + emulator_put_fpu(flags); |
---|
4257 | 4273 | |
---|
4258 | 4274 | return rc; |
---|
4259 | 4275 | } |
---|
.. | .. |
---|
5498 | 5514 | |
---|
5499 | 5515 | static int flush_pending_x87_faults(struct x86_emulate_ctxt *ctxt) |
---|
5500 | 5516 | { |
---|
| 5517 | + unsigned long flags; |
---|
5501 | 5518 | int rc; |
---|
5502 | 5519 | |
---|
5503 | | - emulator_get_fpu(); |
---|
| 5520 | + flags = emulator_get_fpu(); |
---|
5504 | 5521 | rc = asm_safe("fwait"); |
---|
5505 | | - emulator_put_fpu(); |
---|
| 5522 | + emulator_put_fpu(flags); |
---|
5506 | 5523 | |
---|
5507 | 5524 | if (unlikely(rc != X86EMUL_CONTINUE)) |
---|
5508 | 5525 | return emulate_exception(ctxt, MF_VECTOR, 0, false); |
---|