aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2013-09-20 00:52:39 -0400
committerAlexander Graf <agraf@suse.de>2013-10-17 08:45:02 -0400
commit4b8473c9c19dff1b0c672f182cc50b9952cf42e7 (patch)
treec4e91c0612665859589f0cf12d32eff6c8af4990
parenta0144e2a6b0b4a137a32f0102354782547bf0935 (diff)
KVM: PPC: Book3S HV: Add support for guest Program Priority Register
POWER7 and later IBM server processors have a register called the Program Priority Register (PPR), which controls the priority of each hardware CPU SMT thread, and affects how fast it runs compared to other SMT threads. This priority can be controlled by writing to the PPR or by use of a set of instructions of the form or rN,rN,rN which are otherwise no-ops but have been defined to set the priority to particular levels. This adds code to context switch the PPR when entering and exiting guests and to make the PPR value accessible through the SET/GET_ONE_REG interface. When entering the guest, we set the PPR as late as possible, because if we are setting a low thread priority it will make the code run slowly from that point on. Similarly, the first-level interrupt handlers save the PPR value in the PACA very early on, and set the thread priority to the medium level, so that the interrupt handling code runs at a reasonable speed. Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--Documentation/virtual/kvm/api.txt1
-rw-r--r--arch/powerpc/include/asm/exception-64s.h8
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h1
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/include/uapi/asm/kvm.h1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kvm/book3s_hv.c6
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S12
8 files changed, 31 insertions, 1 deletions
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index 387f4c7dad9f..a9d1072dcbec 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1836,6 +1836,7 @@ registers, find a list below:
1836 PPC | KVM_REG_PPC_ACOP | 64 1836 PPC | KVM_REG_PPC_ACOP | 64
1837 PPC | KVM_REG_PPC_VRSAVE | 32 1837 PPC | KVM_REG_PPC_VRSAVE | 32
1838 PPC | KVM_REG_PPC_LPCR | 64 1838 PPC | KVM_REG_PPC_LPCR | 64
1839 PPC | KVM_REG_PPC_PPR | 64
1839 PPC | KVM_REG_PPC_TM_GPR0 | 64 1840 PPC | KVM_REG_PPC_TM_GPR0 | 64
1840 ... 1841 ...
1841 PPC | KVM_REG_PPC_TM_GPR31 | 64 1842 PPC | KVM_REG_PPC_TM_GPR31 | 64
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index cca12f084842..402c1c466509 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -204,6 +204,10 @@ do_kvm_##n: \
204 ld r10,area+EX_CFAR(r13); \ 204 ld r10,area+EX_CFAR(r13); \
205 std r10,HSTATE_CFAR(r13); \ 205 std r10,HSTATE_CFAR(r13); \
206 END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \ 206 END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \
207 BEGIN_FTR_SECTION_NESTED(948) \
208 ld r10,area+EX_PPR(r13); \
209 std r10,HSTATE_PPR(r13); \
210 END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
207 ld r10,area+EX_R10(r13); \ 211 ld r10,area+EX_R10(r13); \
208 stw r9,HSTATE_SCRATCH1(r13); \ 212 stw r9,HSTATE_SCRATCH1(r13); \
209 ld r9,area+EX_R9(r13); \ 213 ld r9,area+EX_R9(r13); \
@@ -217,6 +221,10 @@ do_kvm_##n: \
217 ld r10,area+EX_R10(r13); \ 221 ld r10,area+EX_R10(r13); \
218 beq 89f; \ 222 beq 89f; \
219 stw r9,HSTATE_SCRATCH1(r13); \ 223 stw r9,HSTATE_SCRATCH1(r13); \
224 BEGIN_FTR_SECTION_NESTED(948) \
225 ld r9,area+EX_PPR(r13); \
226 std r9,HSTATE_PPR(r13); \
227 END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \
220 ld r9,area+EX_R9(r13); \ 228 ld r9,area+EX_R9(r13); \
221 std r12,HSTATE_SCRATCH0(r13); \ 229 std r12,HSTATE_SCRATCH0(r13); \
222 li r12,n; \ 230 li r12,n; \
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 9039d3c97eec..22f46061ae84 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -101,6 +101,7 @@ struct kvmppc_host_state {
101#endif 101#endif
102#ifdef CONFIG_PPC_BOOK3S_64 102#ifdef CONFIG_PPC_BOOK3S_64
103 u64 cfar; 103 u64 cfar;
104 u64 ppr;
104#endif 105#endif
105}; 106};
106 107
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 6eabffcb1c3c..4934e13fb23c 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -460,6 +460,7 @@ struct kvm_vcpu_arch {
460 u32 ctrl; 460 u32 ctrl;
461 ulong dabr; 461 ulong dabr;
462 ulong cfar; 462 ulong cfar;
463 ulong ppr;
463#endif 464#endif
464 u32 vrsave; /* also USPRG0 */ 465 u32 vrsave; /* also USPRG0 */
465 u32 mmucr; 466 u32 mmucr;
diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
index e42127d1ae8e..fab6bc1f8e90 100644
--- a/arch/powerpc/include/uapi/asm/kvm.h
+++ b/arch/powerpc/include/uapi/asm/kvm.h
@@ -534,6 +534,7 @@ struct kvm_get_htab_header {
534 534
535#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4) 535#define KVM_REG_PPC_VRSAVE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb4)
536#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5) 536#define KVM_REG_PPC_LPCR (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xb5)
537#define KVM_REG_PPC_PPR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xb6)
537 538
538/* Transactional Memory checkpointed state: 539/* Transactional Memory checkpointed state:
539 * This is all GPRs, all VSX regs and a subset of SPRs 540 * This is all GPRs, all VSX regs and a subset of SPRs
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index fd7513f8014b..5fda4ef489ad 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -519,6 +519,7 @@ int main(void)
519 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); 519 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
520 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid)); 520 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
521 DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); 521 DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
522 DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr));
522 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count)); 523 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
523 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count)); 524 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
524 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest)); 525 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
@@ -604,6 +605,7 @@ int main(void)
604 605
605#ifdef CONFIG_PPC_BOOK3S_64 606#ifdef CONFIG_PPC_BOOK3S_64
606 HSTATE_FIELD(HSTATE_CFAR, cfar); 607 HSTATE_FIELD(HSTATE_CFAR, cfar);
608 HSTATE_FIELD(HSTATE_PPR, ppr);
607#endif /* CONFIG_PPC_BOOK3S_64 */ 609#endif /* CONFIG_PPC_BOOK3S_64 */
608 610
609#else /* CONFIG_PPC_BOOK3S */ 611#else /* CONFIG_PPC_BOOK3S */
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
index 36eb95cc48ae..2a0e38feec1d 100644
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -823,6 +823,9 @@ int kvmppc_get_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
823 case KVM_REG_PPC_LPCR: 823 case KVM_REG_PPC_LPCR:
824 *val = get_reg_val(id, vcpu->arch.vcore->lpcr); 824 *val = get_reg_val(id, vcpu->arch.vcore->lpcr);
825 break; 825 break;
826 case KVM_REG_PPC_PPR:
827 *val = get_reg_val(id, vcpu->arch.ppr);
828 break;
826 default: 829 default:
827 r = -EINVAL; 830 r = -EINVAL;
828 break; 831 break;
@@ -930,6 +933,9 @@ int kvmppc_set_one_reg(struct kvm_vcpu *vcpu, u64 id, union kvmppc_one_reg *val)
930 case KVM_REG_PPC_LPCR: 933 case KVM_REG_PPC_LPCR:
931 kvmppc_set_lpcr(vcpu, set_reg_val(id, *val)); 934 kvmppc_set_lpcr(vcpu, set_reg_val(id, *val));
932 break; 935 break;
936 case KVM_REG_PPC_PPR:
937 vcpu->arch.ppr = set_reg_val(id, *val);
938 break;
933 default: 939 default:
934 r = -EINVAL; 940 r = -EINVAL;
935 break; 941 break;
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 295fd58af39a..a81979becf41 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -717,13 +717,15 @@ BEGIN_FTR_SECTION
717 ld r5, VCPU_CFAR(r4) 717 ld r5, VCPU_CFAR(r4)
718 mtspr SPRN_CFAR, r5 718 mtspr SPRN_CFAR, r5
719END_FTR_SECTION_IFSET(CPU_FTR_CFAR) 719END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
720BEGIN_FTR_SECTION
721 ld r0, VCPU_PPR(r4)
722END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
720 723
721 ld r5, VCPU_LR(r4) 724 ld r5, VCPU_LR(r4)
722 lwz r6, VCPU_CR(r4) 725 lwz r6, VCPU_CR(r4)
723 mtlr r5 726 mtlr r5
724 mtcr r6 727 mtcr r6
725 728
726 ld r0, VCPU_GPR(R0)(r4)
727 ld r1, VCPU_GPR(R1)(r4) 729 ld r1, VCPU_GPR(R1)(r4)
728 ld r2, VCPU_GPR(R2)(r4) 730 ld r2, VCPU_GPR(R2)(r4)
729 ld r3, VCPU_GPR(R3)(r4) 731 ld r3, VCPU_GPR(R3)(r4)
@@ -737,6 +739,10 @@ END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
737 ld r12, VCPU_GPR(R12)(r4) 739 ld r12, VCPU_GPR(R12)(r4)
738 ld r13, VCPU_GPR(R13)(r4) 740 ld r13, VCPU_GPR(R13)(r4)
739 741
742BEGIN_FTR_SECTION
743 mtspr SPRN_PPR, r0
744END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
745 ld r0, VCPU_GPR(R0)(r4)
740 ld r4, VCPU_GPR(R4)(r4) 746 ld r4, VCPU_GPR(R4)(r4)
741 747
742 hrfid 748 hrfid
@@ -787,6 +793,10 @@ BEGIN_FTR_SECTION
787 ld r3, HSTATE_CFAR(r13) 793 ld r3, HSTATE_CFAR(r13)
788 std r3, VCPU_CFAR(r9) 794 std r3, VCPU_CFAR(r9)
789END_FTR_SECTION_IFSET(CPU_FTR_CFAR) 795END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
796BEGIN_FTR_SECTION
797 ld r4, HSTATE_PPR(r13)
798 std r4, VCPU_PPR(r9)
799END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
790 800
791 /* Restore R1/R2 so we can handle faults */ 801 /* Restore R1/R2 so we can handle faults */
792 ld r1, HSTATE_HOST_R1(r13) 802 ld r1, HSTATE_HOST_R1(r13)