aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2013-02-04 13:10:51 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2013-02-15 00:54:33 -0500
commit0acb91112a148fbb31678e66839ef757f3be3aa4 (patch)
tree9516f90d03a55bc07f8b13b67d497dea8062430c
parent1707dd161349e6c54170c88d94fed012e3d224e3 (diff)
powerpc/kvm/book3s_hv: Preserve guest CFAR register value
The CFAR (Come-From Address Register) is a useful debugging aid that exists on POWER7 processors. Currently HV KVM doesn't save or restore the CFAR register for guest vcpus, making the CFAR of limited use in guests. This adds the necessary code to capture the CFAR value saved in the early exception entry code (it has to be saved before any branch is executed), save it in the vcpu.arch struct, and restore it on entry to the guest. Signed-off-by: Paul Mackerras <paulus@samba.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/exception-64s.h8
-rw-r--r--arch/powerpc/include/asm/kvm_book3s_asm.h3
-rw-r--r--arch/powerpc/include/asm/kvm_host.h1
-rw-r--r--arch/powerpc/kernel/asm-offsets.c5
-rw-r--r--arch/powerpc/kvm/book3s_hv_rmhandlers.S9
5 files changed, 24 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h
index 4dfc51588be5..05e6d2ee1db9 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -199,10 +199,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
199 199
200#define __KVM_HANDLER(area, h, n) \ 200#define __KVM_HANDLER(area, h, n) \
201do_kvm_##n: \ 201do_kvm_##n: \
202 BEGIN_FTR_SECTION_NESTED(947) \
203 ld r10,area+EX_CFAR(r13); \
204 std r10,HSTATE_CFAR(r13); \
205 END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \
202 ld r10,area+EX_R10(r13); \ 206 ld r10,area+EX_R10(r13); \
203 stw r9,HSTATE_SCRATCH1(r13); \ 207 stw r9,HSTATE_SCRATCH1(r13); \
204 ld r9,area+EX_R9(r13); \ 208 ld r9,area+EX_R9(r13); \
205 std r12,HSTATE_SCRATCH0(r13); \ 209 std r12,HSTATE_SCRATCH0(r13); \
206 li r12,n; \ 210 li r12,n; \
207 b kvmppc_interrupt 211 b kvmppc_interrupt
208 212
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 88609b23b775..cdc3d2717cc6 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h
@@ -93,6 +93,9 @@ struct kvmppc_host_state {
93 u64 host_dscr; 93 u64 host_dscr;
94 u64 dec_expires; 94 u64 dec_expires;
95#endif 95#endif
96#ifdef CONFIG_PPC_BOOK3S_64
97 u64 cfar;
98#endif
96}; 99};
97 100
98struct kvmppc_book3s_shadow_vcpu { 101struct kvmppc_book3s_shadow_vcpu {
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index ca9bf459db6a..03d7beae89a0 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h
@@ -440,6 +440,7 @@ struct kvm_vcpu_arch {
440 ulong uamor; 440 ulong uamor;
441 u32 ctrl; 441 u32 ctrl;
442 ulong dabr; 442 ulong dabr;
443 ulong cfar;
443#endif 444#endif
444 u32 vrsave; /* also USPRG0 */ 445 u32 vrsave; /* also USPRG0 */
445 u32 mmucr; 446 u32 mmucr;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index beddba432518..e295a09b1f06 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -479,6 +479,7 @@ int main(void)
479 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); 479 DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
480 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap)); 480 DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
481 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid)); 481 DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
482 DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
482 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count)); 483 DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
483 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count)); 484 DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
484 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest)); 485 DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
@@ -558,6 +559,10 @@ int main(void)
558 DEFINE(IPI_PRIORITY, IPI_PRIORITY); 559 DEFINE(IPI_PRIORITY, IPI_PRIORITY);
559#endif /* CONFIG_KVM_BOOK3S_64_HV */ 560#endif /* CONFIG_KVM_BOOK3S_64_HV */
560 561
562#ifdef CONFIG_PPC_BOOK3S_64
563 HSTATE_FIELD(HSTATE_CFAR, cfar);
564#endif /* CONFIG_PPC_BOOK3S_64 */
565
561#else /* CONFIG_PPC_BOOK3S */ 566#else /* CONFIG_PPC_BOOK3S */
562 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr)); 567 DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
563 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer)); 568 DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index 10b6c358dd77..e33d11f1b977 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -539,6 +539,11 @@ fast_guest_return:
539 539
540 /* Enter guest */ 540 /* Enter guest */
541 541
542BEGIN_FTR_SECTION
543 ld r5, VCPU_CFAR(r4)
544 mtspr SPRN_CFAR, r5
545END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
546
542 ld r5, VCPU_LR(r4) 547 ld r5, VCPU_LR(r4)
543 lwz r6, VCPU_CR(r4) 548 lwz r6, VCPU_CR(r4)
544 mtlr r5 549 mtlr r5
@@ -604,6 +609,10 @@ kvmppc_interrupt:
604 lwz r4, HSTATE_SCRATCH1(r13) 609 lwz r4, HSTATE_SCRATCH1(r13)
605 std r3, VCPU_GPR(R12)(r9) 610 std r3, VCPU_GPR(R12)(r9)
606 stw r4, VCPU_CR(r9) 611 stw r4, VCPU_CR(r9)
612BEGIN_FTR_SECTION
613 ld r3, HSTATE_CFAR(r13)
614 std r3, VCPU_CFAR(r9)
615END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
607 616
608 /* Restore R1/R2 so we can handle faults */ 617 /* Restore R1/R2 so we can handle faults */
609 ld r1, HSTATE_HOST_R1(r13) 618 ld r1, HSTATE_HOST_R1(r13)