Skip to content

Commit

Permalink
powerpc/kvm/book3s_hv: Preserve guest CFAR register value
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Paul Mackerras authored and Benjamin Herrenschmidt committed Feb 15, 2013
1 parent 1707dd1 commit 0acb911
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 2 deletions.
8 changes: 6 additions & 2 deletions arch/powerpc/include/asm/exception-64s.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)

#define __KVM_HANDLER(area, h, n) \
do_kvm_##n: \
BEGIN_FTR_SECTION_NESTED(947) \
ld r10,area+EX_CFAR(r13); \
std r10,HSTATE_CFAR(r13); \
END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \
ld r10,area+EX_R10(r13); \
stw r9,HSTATE_SCRATCH1(r13); \
stw r9,HSTATE_SCRATCH1(r13); \
ld r9,area+EX_R9(r13); \
std r12,HSTATE_SCRATCH0(r13); \
std r12,HSTATE_SCRATCH0(r13); \
li r12,n; \
b kvmppc_interrupt

Expand Down
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/kvm_book3s_asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ struct kvmppc_host_state {
u64 host_dscr;
u64 dec_expires;
#endif
#ifdef CONFIG_PPC_BOOK3S_64
u64 cfar;
#endif
};

struct kvmppc_book3s_shadow_vcpu {
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ struct kvm_vcpu_arch {
ulong uamor;
u32 ctrl;
ulong dabr;
ulong cfar;
#endif
u32 vrsave; /* also USPRG0 */
u32 mmucr;
Expand Down
5 changes: 5 additions & 0 deletions arch/powerpc/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ int main(void)
DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst));
DEFINE(VCPU_TRAP, offsetof(struct kvm_vcpu, arch.trap));
DEFINE(VCPU_PTID, offsetof(struct kvm_vcpu, arch.ptid));
DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar));
DEFINE(VCORE_ENTRY_EXIT, offsetof(struct kvmppc_vcore, entry_exit_count));
DEFINE(VCORE_NAP_COUNT, offsetof(struct kvmppc_vcore, nap_count));
DEFINE(VCORE_IN_GUEST, offsetof(struct kvmppc_vcore, in_guest));
Expand Down Expand Up @@ -558,6 +559,10 @@ int main(void)
DEFINE(IPI_PRIORITY, IPI_PRIORITY);
#endif /* CONFIG_KVM_BOOK3S_64_HV */

#ifdef CONFIG_PPC_BOOK3S_64
HSTATE_FIELD(HSTATE_CFAR, cfar);
#endif /* CONFIG_PPC_BOOK3S_64 */

#else /* CONFIG_PPC_BOOK3S */
DEFINE(VCPU_CR, offsetof(struct kvm_vcpu, arch.cr));
DEFINE(VCPU_XER, offsetof(struct kvm_vcpu, arch.xer));
Expand Down
9 changes: 9 additions & 0 deletions arch/powerpc/kvm/book3s_hv_rmhandlers.S
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,11 @@ fast_guest_return:

/* Enter guest */

BEGIN_FTR_SECTION
ld r5, VCPU_CFAR(r4)
mtspr SPRN_CFAR, r5
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)

ld r5, VCPU_LR(r4)
lwz r6, VCPU_CR(r4)
mtlr r5
Expand Down Expand Up @@ -604,6 +609,10 @@ kvmppc_interrupt:
lwz r4, HSTATE_SCRATCH1(r13)
std r3, VCPU_GPR(R12)(r9)
stw r4, VCPU_CR(r9)
BEGIN_FTR_SECTION
ld r3, HSTATE_CFAR(r13)
std r3, VCPU_CFAR(r9)
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)

/* Restore R1/R2 so we can handle faults */
ld r1, HSTATE_HOST_R1(r13)
Expand Down

0 comments on commit 0acb911

Please sign in to comment.