aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2014-04-22 06:26:58 -0400
committerAlexander Graf <agraf@suse.de>2014-05-30 08:26:23 -0400
commite14e7a1e537d6e18f9c511f25c25c5efb7799fb5 (patch)
treef0e8f7c0450dcbb83ea1f6e527b99e69e23f8e9a
parent616dff86028298dbc91174fb3d12b8ed8cd74955 (diff)
KVM: PPC: Book3S PR: Expose TAR facility to guest
POWER8 implements a new register called TAR. This register has to be enabled in FSCR and then from KVM's point of view is mere storage. This patch enables the guest to use TAR. Signed-off-by: Alexander Graf <agraf@suse.de>
-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;