diff options
author | Andreas Schwab <schwab@linux-m68k.org> | 2010-05-31 15:59:13 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-08-01 03:39:24 -0400 |
commit | 49f6be8ea1bd74713c1a48e42db06a3808dfa2cd (patch) | |
tree | 5be35ebab7a049e9358a60b308df981b02f70f21 /arch/powerpc/kvm/book3s.c | |
parent | 5120702e732ed72c7055f511f8dd01de36424569 (diff) |
KVM: PPC: elide struct thread_struct instances from stack
Instead of instantiating a whole thread_struct on the stack use only the
required parts of it.
Signed-off-by: Andreas Schwab <schwab@linux-m68k.org>
Tested-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/powerpc/kvm/book3s.c')
-rw-r--r-- | arch/powerpc/kvm/book3s.c | 49 |
1 files changed, 27 insertions, 22 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index f6eac2f337d9..801d9f3c70ae 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c | |||
@@ -1293,12 +1293,17 @@ extern int __kvmppc_vcpu_entry(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu); | |||
1293 | int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | 1293 | int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) |
1294 | { | 1294 | { |
1295 | int ret; | 1295 | int ret; |
1296 | struct thread_struct ext_bkp; | 1296 | double fpr[32][TS_FPRWIDTH]; |
1297 | unsigned int fpscr; | ||
1298 | int fpexc_mode; | ||
1297 | #ifdef CONFIG_ALTIVEC | 1299 | #ifdef CONFIG_ALTIVEC |
1298 | bool save_vec = current->thread.used_vr; | 1300 | vector128 vr[32]; |
1301 | vector128 vscr; | ||
1302 | unsigned long uninitialized_var(vrsave); | ||
1303 | int used_vr; | ||
1299 | #endif | 1304 | #endif |
1300 | #ifdef CONFIG_VSX | 1305 | #ifdef CONFIG_VSX |
1301 | bool save_vsx = current->thread.used_vsr; | 1306 | int used_vsr; |
1302 | #endif | 1307 | #endif |
1303 | ulong ext_msr; | 1308 | ulong ext_msr; |
1304 | 1309 | ||
@@ -1311,27 +1316,27 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1311 | /* Save FPU state in stack */ | 1316 | /* Save FPU state in stack */ |
1312 | if (current->thread.regs->msr & MSR_FP) | 1317 | if (current->thread.regs->msr & MSR_FP) |
1313 | giveup_fpu(current); | 1318 | giveup_fpu(current); |
1314 | memcpy(ext_bkp.fpr, current->thread.fpr, sizeof(current->thread.fpr)); | 1319 | memcpy(fpr, current->thread.fpr, sizeof(current->thread.fpr)); |
1315 | ext_bkp.fpscr = current->thread.fpscr; | 1320 | fpscr = current->thread.fpscr.val; |
1316 | ext_bkp.fpexc_mode = current->thread.fpexc_mode; | 1321 | fpexc_mode = current->thread.fpexc_mode; |
1317 | 1322 | ||
1318 | #ifdef CONFIG_ALTIVEC | 1323 | #ifdef CONFIG_ALTIVEC |
1319 | /* Save Altivec state in stack */ | 1324 | /* Save Altivec state in stack */ |
1320 | if (save_vec) { | 1325 | used_vr = current->thread.used_vr; |
1326 | if (used_vr) { | ||
1321 | if (current->thread.regs->msr & MSR_VEC) | 1327 | if (current->thread.regs->msr & MSR_VEC) |
1322 | giveup_altivec(current); | 1328 | giveup_altivec(current); |
1323 | memcpy(ext_bkp.vr, current->thread.vr, sizeof(ext_bkp.vr)); | 1329 | memcpy(vr, current->thread.vr, sizeof(current->thread.vr)); |
1324 | ext_bkp.vscr = current->thread.vscr; | 1330 | vscr = current->thread.vscr; |
1325 | ext_bkp.vrsave = current->thread.vrsave; | 1331 | vrsave = current->thread.vrsave; |
1326 | } | 1332 | } |
1327 | ext_bkp.used_vr = current->thread.used_vr; | ||
1328 | #endif | 1333 | #endif |
1329 | 1334 | ||
1330 | #ifdef CONFIG_VSX | 1335 | #ifdef CONFIG_VSX |
1331 | /* Save VSX state in stack */ | 1336 | /* Save VSX state in stack */ |
1332 | if (save_vsx && (current->thread.regs->msr & MSR_VSX)) | 1337 | used_vsr = current->thread.used_vsr; |
1338 | if (used_vsr && (current->thread.regs->msr & MSR_VSX)) | ||
1333 | __giveup_vsx(current); | 1339 | __giveup_vsx(current); |
1334 | ext_bkp.used_vsr = current->thread.used_vsr; | ||
1335 | #endif | 1340 | #endif |
1336 | 1341 | ||
1337 | /* Remember the MSR with disabled extensions */ | 1342 | /* Remember the MSR with disabled extensions */ |
@@ -1356,22 +1361,22 @@ int __kvmppc_vcpu_run(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
1356 | kvmppc_giveup_ext(vcpu, MSR_VSX); | 1361 | kvmppc_giveup_ext(vcpu, MSR_VSX); |
1357 | 1362 | ||
1358 | /* Restore FPU state from stack */ | 1363 | /* Restore FPU state from stack */ |
1359 | memcpy(current->thread.fpr, ext_bkp.fpr, sizeof(ext_bkp.fpr)); | 1364 | memcpy(current->thread.fpr, fpr, sizeof(current->thread.fpr)); |
1360 | current->thread.fpscr = ext_bkp.fpscr; | 1365 | current->thread.fpscr.val = fpscr; |
1361 | current->thread.fpexc_mode = ext_bkp.fpexc_mode; | 1366 | current->thread.fpexc_mode = fpexc_mode; |
1362 | 1367 | ||
1363 | #ifdef CONFIG_ALTIVEC | 1368 | #ifdef CONFIG_ALTIVEC |
1364 | /* Restore Altivec state from stack */ | 1369 | /* Restore Altivec state from stack */ |
1365 | if (save_vec && current->thread.used_vr) { | 1370 | if (used_vr && current->thread.used_vr) { |
1366 | memcpy(current->thread.vr, ext_bkp.vr, sizeof(ext_bkp.vr)); | 1371 | memcpy(current->thread.vr, vr, sizeof(current->thread.vr)); |
1367 | current->thread.vscr = ext_bkp.vscr; | 1372 | current->thread.vscr = vscr; |
1368 | current->thread.vrsave= ext_bkp.vrsave; | 1373 | current->thread.vrsave = vrsave; |
1369 | } | 1374 | } |
1370 | current->thread.used_vr = ext_bkp.used_vr; | 1375 | current->thread.used_vr = used_vr; |
1371 | #endif | 1376 | #endif |
1372 | 1377 | ||
1373 | #ifdef CONFIG_VSX | 1378 | #ifdef CONFIG_VSX |
1374 | current->thread.used_vsr = ext_bkp.used_vsr; | 1379 | current->thread.used_vsr = used_vsr; |
1375 | #endif | 1380 | #endif |
1376 | 1381 | ||
1377 | return ret; | 1382 | return ret; |