KVM: PPC: Fixes for PR-KVM on POWER7
Subsystems (3)
cover KVM: PPC: Fixes for PR-KVM on POWER7
Here are some fixes for PR-style KVM. With these I can successfully run a pseries (PAPR) guest under PR KVM on a POWER7. (This is all running inside a HV KVM virtual machine.) The patches are against Alex Graf's kvm-ppc-next branch.
Paul.
PATCH 1/3 KVM: PPC: Book3S PR: Emulate PURR, SPURR and DSCR registers
This adds basic emulation of the PURR and SPURR registers. We assume we are emulating a single-threaded core, so these advance at the same rate as the timebase. A Linux kernel running on a POWER7 expects to be able to access these registers and is not prepared to handle a program interrupt on accessing them.
This also adds a very minimal emulation of the DSCR (data stream control register). Writes are ignored and reads return zero.
---
This adds these registers for all CPUs; currently we don't seem to make the presence or absence of SPRs depend on the PVR, but maybe we should.
arch/powerpc/include/asm/kvm_book3s.h | 2 ++ arch/powerpc/kvm/book3s_emulate.c | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/kvm_book3s.h +2 -0
@@ -81,6 +81,8 @@ struct kvmppc_vcpu_book3s {u64 sdr1;u64 hior;u64 msr_mask; +u64 purr_offset; +u64 spurr_offset;#ifdef CONFIG_PPC_BOOK3S_32 u32 vsid_pool[VSID_POOL_SIZE ];u32 vsid_next;
arch/powerpc/kvm/book3s_emulate.c +15 -1
@@ -22,6 +22,7 @@#include <asm/kvm_book3s.h> #include <asm/reg.h> #include <asm/switch_to.h> +#include <asm/time.h> #define OP_19_XOP_RFID 18#define OP_19_XOP_RFI 50
@@ -395,6 +396,12 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) (mfmsr() & MSR_HV)) vcpu->arch.hflags |=BOOK3S_HFLAG_DCBZ32 ;break ; +case SPRN_PURR : +to_book3s (vcpu)->purr_offset = spr_val -get_tb (); +break ; +case SPRN_SPURR : +to_book3s (vcpu)->spurr_offset = spr_val -get_tb (); +break ;case SPRN_GQR0 :case SPRN_GQR1 :case SPRN_GQR2 :
@@ -412,6 +419,7 @@ int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)case SPRN_CTRLF :case SPRN_CTRLT :case SPRN_L2CR : +case SPRN_DSCR :case SPRN_MMCR0_GEKKO :case SPRN_MMCR1_GEKKO :case SPRN_PMC1_GEKKO :
@@ -483,9 +491,15 @@ int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val) *spr_val =to_book3s (vcpu)->hid[5 ];break ;case SPRN_CFAR : -case SPRN_PURR : +case SPRN_DSCR : *spr_val =0 ;break ; +case SPRN_PURR : + *spr_val =get_tb () +to_book3s (vcpu)->purr_offset; +break ; +case SPRN_SPURR : + *spr_val =get_tb () +to_book3s (vcpu)->purr_offset; +break ;case SPRN_GQR0 :case SPRN_GQR1 :case SPRN_GQR2 :
Signature · 1 line
1.7.10.4
PATCH 2/3 KVM: PPC: Book3S PR: Fix VSX handling
In reply to Paul MackerrasThis fixes various issues in how we were handling the VSX registers that exist on POWER7 machines. First, we were running off the end of the current->thread.fpr[] array. Ultimately this was because the vcpu->arch.vsr[] array is sized to be able to store both the FP registers and the extra VSX registers (i.e. 64 entries), but PR KVM only uses it for the extra VSX registers (i.e. 32 entries).
Secondly, calling load_up_vsx() from C code is a really bad idea, because it jumps to fast_exception_return at the end, rather than returning with a blr instruction. This was causing it to jump off to a random location with random register contents, since it was using the largely uninitialized stack frame created by kvmppc_load_up_vsx.
In fact, it isn't necessary to call either __giveup_vsx or load_up_vsx, since giveup_fpu and load_up_fpu handle the extra VSX registers as well as the standard FP registers on machines with VSX. Also, since VSX instructions can access the VMX registers and the FP registers as well as the extra VSX registers, we have to load up the FP and VMX registers before we can turn on the MSR_VSX bit for the guest. Conversely, if we save away any of the VSX or FP registers, we have to turn off MSR_VSX for the guest.
To handle all this, it is more convenient for a single call to kvmppc_giveup_ext() to handle all the state saving that needs to be done, so we make it take a set of MSR bits rather than just one, and the switch statement becomes a series of if statements. Similarly kvmppc_handle_ext needs to be able to load up more than one set of registers.
--- arch/powerpc/include/asm/reg.h | 1 + arch/powerpc/kvm/book3s_exports.c | 3 - arch/powerpc/kvm/book3s_pr.c | 112 ++++++++++++++++++---------------- arch/powerpc/kvm/book3s_rmhandlers.S | 3 - 4 files changed, 62 insertions(+), 57 deletions(-)
arch/powerpc/include/asm/reg.h +1 -0
@@ -515,6 +515,7 @@#define SRR1_WS_DEEPER 0x00020000/* Some resources not maintained */ #define SRR1_WS_DEEP 0x00010000/* All resources maintained */ #define SRR1_PROGFPE 0x00100000/* Floating Point Enabled */ +#define SRR1_PROGILL 0x00080000/* Illegal instruction */ #define SRR1_PROGPRIV 0x00040000/* Privileged instruction */ #define SRR1_PROGTRAP 0x00020000/* Trap */ #define SRR1_PROGADDR 0x00010000/* SRR0 contains subsequent addr */
arch/powerpc/kvm/book3s_exports.c +0 -3
@@ -28,8 +28,5 @@ EXPORT_SYMBOL_GPL(kvmppc_load_up_fpu);#ifdef CONFIG_ALTIVEC EXPORT_SYMBOL_GPL (kvmppc_load_up_altivec);#endif -#ifdef CONFIG_VSX -EXPORT_SYMBOL_GPL (kvmppc_load_up_vsx); -#endif #endif
arch/powerpc/kvm/book3s_pr.c +61 -51
189 lines not on this page · raw message
arch/powerpc/kvm/book3s_rmhandlers.S +0 -3
@@ -234,8 +234,5 @@ define_load_up(fpu) #ifdef CONFIG_ALTIVEC define_load_up(altivec) #endif -#ifdef CONFIG_VSX -define_load_up(vsx) -#endif #include "book3s_segment.S"
Signature · 1 line
1.7.10.4
PATCH 3/3 KVM: PPC: Book3S PR: MSR_DE doesn't exist on Book 3S
In reply to Paul MackerrasThe mask of MSR bits that get transferred from the guest MSR to the shadow MSR included MSR_DE. In fact that bit only exists on Book 3E processors, and it is assigned the same bit used for MSR_BE on Book 3S processors. Since we already had MSR_BE in the mask, this just removes MSR_DE.
--- arch/powerpc/kvm/book3s_pr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/powerpc/kvm/book3s_pr.c +1 -1
@@ -145,7 +145,7 @@ static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)ulong smsr = vcpu->arch.shared->msr;/* Guest MSR values */ - smsr &=MSR_FE0 |MSR_FE1 |MSR_SF |MSR_SE |MSR_BE |MSR_DE ; + smsr &=MSR_FE0 |MSR_FE1 |MSR_SF |MSR_SE |MSR_BE ;/* Process MSR values */ smsr |=MSR_ME |MSR_RI |MSR_IR |MSR_DR |MSR_PR |MSR_EE ;/* External providers the guest reserved */
Signature · 1 line
1.7.10.4
Quoted 4 lines · Paul Mackerras
Here are some fixes for PR-style KVM. With these I can successfully run a pseries (PAPR) guest under PR KVM on a POWER7. (This is all running inside a HV KVM virtual machine.) The patches are against Alex Graf's kvm-ppc-next branch.
Thanks a lot! Applied all to kvm-ppc-next.
Alex