aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/include/asm/kvm_host.h2
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kvm/book3s.c6
-rw-r--r--arch/powerpc/kvm/book3s_hv.c6
-rw-r--r--arch/powerpc/kvm/book3s_pr.c18
5 files changed, 28 insertions, 6 deletions
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 232ec5f0b886..29fbb554af5c 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -449,7 +449,9 @@ struct kvm_vcpu_arch {
449 ulong pc; 449 ulong pc;
450 ulong ctr; 450 ulong ctr;
451 ulong lr; 451 ulong lr;
452#ifdef CONFIG_PPC_BOOK3S
452 ulong tar; 453 ulong tar;
454#endif
453 455
454 ulong xer; 456 ulong xer;
455 u32 cr; 457 u32 cr;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index e2b86b5c02b3..93e1465c8496 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -446,7 +446,9 @@ int main(void)
446 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); 446 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
447 DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr)); 447 DEFINE(VCPU_CTR, offsetof(struct kvm_vcpu, arch.ctr));
448 DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr)); 448 DEFINE(VCPU_LR, offsetof(struct kvm_vcpu, arch.lr));
449#ifdef CONFIG_PPC_BOOK3S
449 DEFINE(VCPU_TAR, offsetof(struct kvm_vcpu, arch.tar)); 450 DEFINE(VCPU_TAR, offsetof(struct kvm_vcpu, arch.tar));
451#endif
450 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); 452 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
451 DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc)); 453 DEFINE(VCPU_PC, offsetof(struct kvm_vcpu, arch.pc));
452#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE 454#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 79cfa2d10238..4046a1a91a75 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -634,6 +634,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
634 case KVM_REG_PPC_FSCR: 634 case KVM_REG_PPC_FSCR:
635 val = get_reg_val(reg->id, vcpu->arch.fscr); 635 val = get_reg_val(reg->id, vcpu->arch.fscr);
636 break; 636 break;
637 case KVM_REG_PPC_TAR:
638 val = get_reg_val(reg->id, vcpu->arch.tar);
639 break;
637 default: 640 default:
638 r = -EINVAL; 641 r = -EINVAL;
639 break; 642 break;
@@ -726,6 +729,9 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg)
726 case KVM_REG_PPC_FSCR: 729 case KVM_REG_PPC_FSCR:
727 vcpu->arch.fscr = set_reg_val(reg->id, val); 730 vcpu->arch.fscr = set_reg_val(reg->id, val);
728 break; 731 break;
732 case KVM_REG_PPC_TAR:
733 vcpu->arch.tar = set_reg_val(reg->id, val);
734 break;
729 default: 735 default:
730 r = -EINVAL; 736 r = -EINVAL;
731 break; 737 break;
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 0092e12b3e46..ee1d8ee5f1a7 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -891,9 +891,6 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
891 case KVM_REG_PPC_BESCR: 891 case KVM_REG_PPC_BESCR:
892 *val = get_reg_val(id, vcpu->arch.bescr); 892 *val = get_reg_val(id, vcpu->arch.bescr);
893 break; 893 break;
894 case KVM_REG_PPC_TAR:
895 *val = get_reg_val(id, vcpu->arch.tar);
896 break;
897 case KVM_REG_PPC_DPDES: 894 case KVM_REG_PPC_DPDES:
898 *val = get_reg_val(id, vcpu->arch.vcore->dpdes); 895 *val = get_reg_val(id, vcpu->arch.vcore->dpdes);
899 break; 896 break;
@@ -1100,9 +1097,6 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
1100 case KVM_REG_PPC_BESCR: 1097 case KVM_REG_PPC_BESCR:
1101 vcpu->arch.bescr = set_reg_val(id, *val); 1098 vcpu->arch.bescr = set_reg_val(id, *val);
1102 break; 1099 break;
1103 case KVM_REG_PPC_TAR:
1104 vcpu->arch.tar = set_reg_val(id, *val);
1105 break;
1106 case KVM_REG_PPC_DPDES: 1100 case KVM_REG_PPC_DPDES:
1107 vcpu->arch.vcore->dpdes = set_reg_val(id, *val); 1101 vcpu->arch.vcore->dpdes = set_reg_val(id, *val);
1108 break; 1102 break;
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index ddc626eea2da..7d27a9518f07 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c
@@ -90,6 +90,7 @@ static void kvmppc_core_vcpu_put_pr(struct kvm_vcpu *vcpu)
90#endif 90#endif
91 91
92 kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); 92 kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX);
93 kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
93 vcpu->cpu = -1; 94 vcpu->cpu = -1;
94} 95}
95 96
@@ -625,6 +626,14 @@ static void kvmppc_giveup_fac(struct kvm_vcpu *vcpu, ulong fac)
625 /* Facility not available to the guest, ignore giveup request*/ 626 /* Facility not available to the guest, ignore giveup request*/
626 return; 627 return;
627 } 628 }
629
630 switch (fac) {
631 case FSCR_TAR_LG:
632 vcpu->arch.tar = mfspr(SPRN_TAR);
633 mtspr(SPRN_TAR, current->thread.tar);
634 vcpu->arch.shadow_fscr &= ~FSCR_TAR;
635 break;
636 }
628#endif 637#endif
629} 638}
630 639
@@ -794,6 +803,12 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
794 } 803 }
795 804
796 switch (fac) { 805 switch (fac) {
806 case FSCR_TAR_LG:
807 /* TAR switching isn't lazy in Linux yet */
808 current->thread.tar = mfspr(SPRN_TAR);
809 mtspr(SPRN_TAR, vcpu->arch.tar);
810 vcpu->arch.shadow_fscr |= FSCR_TAR;
811 break;
797 default: 812 default:
798 kvmppc_emulate_fac(vcpu, fac); 813 kvmppc_emulate_fac(vcpu, fac);
799 break; 814 break;
@@ -1393,6 +1408,9 @@ static int kvmppc_vcpu_run_pr(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
1393 /* Make sure we save the guest FPU/Altivec/VSX state */ 1408 /* Make sure we save the guest FPU/Altivec/VSX state */
1394 kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX); 1409 kvmppc_giveup_ext(vcpu, MSR_FP | MSR_VEC | MSR_VSX);
1395 1410
1411 /* Make sure we save the guest TAR/EBB/DSCR state */
1412 kvmppc_giveup_fac(vcpu, FSCR_TAR_LG);
1413
1396out: 1414out:
1397 vcpu->mode = OUTSIDE_GUEST_MODE; 1415 vcpu->mode = OUTSIDE_GUEST_MODE;
1398 return ret; 1416 return ret;