[RFC PATCH 01/10] KVM: PPC: BOOK3S: PR: Add POWER8 support
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:31
Hello, This patch series implements PR KVM support for POWER8 platform -aneesh
33 messages, 4 authors, 2014-02-05 · open the first message on its own page
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:31
Hello, This patch series implements PR KVM support for POWER8 platform -aneesh
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:32
We definitely don't need to emulate mtspr, because both the registers are hypervisor resource. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_book3s.h | 2 -- arch/powerpc/include/asm/kvm_host.h | 4 ++-- arch/powerpc/kvm/book3s_emulate.c | 16 ++++++++-------- arch/powerpc/kvm/book3s_pr.c | 10 ++++++++++ 4 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index bc23b1ba7980..396448afa38b 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h@@ -83,8 +83,6 @@ 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;
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 9a0cdb2c9d58..0a3785271f34 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h@@ -506,8 +506,8 @@ struct kvm_vcpu_arch { #ifdef CONFIG_BOOKE u32 decar; #endif - u32 tbl; - u32 tbu; + /* Time base value when we entered the guest */ + u64 entry_tb; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index a7d54aa203d0..e1f1e5e16449 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -422,12 +422,6 @@ int kvmppc_core_emulate_mtspr_pr(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:
@@ -523,10 +517,16 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val *spr_val = 0; break; case SPRN_PURR: - *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; + /* + * On exit we would have updated purr + */ + *spr_val = vcpu->arch.purr; break; case SPRN_SPURR: - *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; + /* + * On exit we would have updated spurr + */ + *spr_val = vcpu->arch.spurr; break; case SPRN_GQR0: case SPRN_GQR1:
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index fdcbabdfb709..02231f5193c2 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c@@ -115,6 +115,11 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, svcpu->lr = vcpu->arch.lr; svcpu->pc = vcpu->arch.pc; svcpu->in_use = true; + /* + * Now also save the current time base value. We use this + * to find the guest purr and spurr value. + */ + vcpu->arch.entry_tb = get_tb(); } /* Copy data touched by real-mode code from shadow vcpu back to vcpu */
@@ -161,6 +166,11 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, out: preempt_enable(); + /* + * Update purr and spurr using time base + */ + vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; + vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; } static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:33
virtual time base register is a per vm register and need to saved and restored on vm exit and entry. Writing to VTB is not allowed in the privileged mode. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/reg.h | 7 +++++++ arch/powerpc/include/asm/time.h | 12 ++++++++++++ arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 3 +++ 5 files changed, 26 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 0a3785271f34..9ebdd12e50a9 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h@@ -508,6 +508,7 @@ struct kvm_vcpu_arch { #endif /* Time base value when we entered the guest */ u64 entry_tb; + u64 entry_vtb; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];
diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index e789f76c9bc2..6c649355b1e9 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h@@ -1161,6 +1161,13 @@ #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ : "r" ((unsigned long)(v)) \ : "memory") +#ifdef CONFIG_PPC_BOOK3S_64 +#define mfvtb() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : \ + "=r" (rval) : "i" (SPRN_VTB)); rval;}) +#else +#define mfvtb() BUG() +#endif #ifdef __powerpc64__ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E)
diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h
index c1f267694acb..1e89dbc665d9 100644
--- a/arch/powerpc/include/asm/time.h
+++ b/arch/powerpc/include/asm/time.h@@ -101,6 +101,18 @@ static inline u64 get_rtc(void) return (u64)hi * 1000000000 + lo; } +#ifdef CONFIG_PPC_BOOK3S_64 +static inline u64 get_vtb(void) +{ + return mfvtb(); +} +#else +static inline u64 get_vtb(void) +{ + return 0; +} +#endif + #ifdef CONFIG_PPC64 static inline u64 get_tb(void) {
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index e1f1e5e16449..4b58d8a90cb5 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -528,6 +528,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val */ *spr_val = vcpu->arch.spurr; break; + case SPRN_VTB: + *spr_val = vcpu->arch.vtb; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 02231f5193c2..b5598e9cdd09 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c@@ -120,6 +120,8 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, * to find the guest purr and spurr value. */ vcpu->arch.entry_tb = get_tb(); + vcpu->arch.entry_vtb = get_vtb(); + } /* Copy data touched by real-mode code from shadow vcpu back to vcpu */
@@ -171,6 +173,7 @@ out: */ vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; + vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; } static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:35
Writing to IC is not allowed in the privileged mode. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 2 ++ 3 files changed, 6 insertions(+)
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index 9ebdd12e50a9..e0b13aca98e6 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h@@ -509,6 +509,7 @@ struct kvm_vcpu_arch { /* Time base value when we entered the guest */ u64 entry_tb; u64 entry_vtb; + u64 entry_ic; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 4b58d8a90cb5..abe6f3057e5b 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -531,6 +531,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_VTB: *spr_val = vcpu->arch.vtb; break; + case SPRN_IC: + *spr_val = vcpu->arch.ic; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index b5598e9cdd09..51d469f8c9fd 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c@@ -121,6 +121,7 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, */ vcpu->arch.entry_tb = get_tb(); vcpu->arch.entry_vtb = get_vtb(); + vcpu->arch.entry_ic = mfspr(SPRN_IC); }
@@ -174,6 +175,7 @@ out: vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; + vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic; } static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:37
Since we don't support SMT yet, we should always find zero in Directed privileged doorbell exception state register. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/kvm/book3s_emulate.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 9cf0392e3dcf..7f25adbd2590 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -585,6 +585,12 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val */ *spr_val = 0; break; + case SPRN_DPDES: + /* + * We don't have SMT support for PR yet, hence always return 0 + */ + *spr_val = 0; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:38
We don't have SMT support yet, hence we should not find a doorbell message generated Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/kvm/book3s_emulate.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index e74dda36ebea..9cf0392e3dcf 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -28,7 +28,9 @@ #define OP_19_XOP_RFI 50 #define OP_31_XOP_MFMSR 83 +#define OP_31_XOP_MSGSNDP 142 #define OP_31_XOP_MTMSR 146 +#define OP_31_XOP_MSGCLRP 174 #define OP_31_XOP_MTMSRD 178 #define OP_31_XOP_MTSR 210 #define OP_31_XOP_MTSRIN 242
@@ -286,6 +288,22 @@ int kvmppc_core_emulate_op_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, break; } + case OP_31_XOP_MSGSNDP: + { + /* + * PR KVM still don't support SMT mode. So we should + * not see a MSGSNDP/MSGCLRP used with PR KVM + */ + pr_info("KVM: MSGSNDP used in non SMT case\n"); + emulated = EMULATE_FAIL; + break; + } + case OP_31_XOP_MSGCLRP: + { + pr_info"KVM: MSGCLRP used in non SMT case\n"); + emulated = EMULATE_FAIL; + break; + } default: emulated = EMULATE_FAIL; }
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:38
Since PR KVM doesn't support SMT yet, we always return 0. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/kvm/book3s_emulate.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index abe6f3057e5b..e74dda36ebea 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -561,6 +561,12 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_DABR: *spr_val = 0; break; + case SPRN_TIR: + /* + * We don't have SMT support for PR yet, hence always return 0 + */ + *spr_val = 0; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:39
At this point we allow all the supported facilities except EBB. So forward the interrupt to guest as illegal instruction. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_asm.h | 4 +++- arch/powerpc/kvm/book3s.c | 4 ++++ arch/powerpc/kvm/book3s_emulate.c | 18 ++++++++++++++++++ arch/powerpc/kvm/book3s_pr.c | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h
index 1bd92fd43cfb..799244face51 100644
--- a/arch/powerpc/include/asm/kvm_asm.h
+++ b/arch/powerpc/include/asm/kvm_asm.h@@ -99,6 +99,7 @@ #define BOOK3S_INTERRUPT_PERFMON 0xf00 #define BOOK3S_INTERRUPT_ALTIVEC 0xf20 #define BOOK3S_INTERRUPT_VSX 0xf40 +#define BOOK3S_INTERRUPT_FAC_UNAVAIL 0xf60 #define BOOK3S_IRQPRIO_SYSTEM_RESET 0 #define BOOK3S_IRQPRIO_DATA_SEGMENT 1
@@ -117,7 +118,8 @@ #define BOOK3S_IRQPRIO_DECREMENTER 14 #define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15 #define BOOK3S_IRQPRIO_EXTERNAL_LEVEL 16 -#define BOOK3S_IRQPRIO_MAX 17 +#define BOOK3S_IRQPRIO_FAC_UNAVAIL 17 +#define BOOK3S_IRQPRIO_MAX 18 #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 8912608b7e1b..a9aea28c2677 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c@@ -143,6 +143,7 @@ static int kvmppc_book3s_vec2irqprio(unsigned int vec) case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break; case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break; case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break; + case 0xf60: prio = BOOK3S_IRQPRIO_FAC_UNAVAIL; break; default: prio = BOOK3S_IRQPRIO_MAX; break; }
@@ -273,6 +274,9 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR: vec = BOOK3S_INTERRUPT_PERFMON; break; + case BOOK3S_IRQPRIO_FAC_UNAVAIL: + vec = BOOK3S_INTERRUPT_FAC_UNAVAIL; + break; default: deliver = 0; printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 60d0b6b745e7..bf6b11021250 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -481,6 +481,15 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) vcpu->arch.shadow_fscr = vcpu->arch.fscr & host_fscr; break; } + case SPRN_EBBHR: + vcpu->arch.ebbhr = spr_val; + break; + case SPRN_EBBRR: + vcpu->arch.ebbrr = spr_val; + break; + case SPRN_BESCR: + vcpu->arch.bescr = spr_val; + break; unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
@@ -607,6 +616,15 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_FSCR: *spr_val = vcpu->arch.fscr; break; + case SPRN_EBBHR: + *spr_val = vcpu->arch.ebbhr; + break; + case SPRN_EBBRR: + *spr_val = vcpu->arch.ebbrr; + break; + case SPRN_BESCR: + *spr_val = vcpu->arch.bescr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c
index 51d469f8c9fd..828056ec208f 100644
--- a/arch/powerpc/kvm/book3s_pr.c
+++ b/arch/powerpc/kvm/book3s_pr.c@@ -900,6 +900,23 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_PERFMON: r = RESUME_GUEST; break; + case BOOK3S_INTERRUPT_FAC_UNAVAIL: + { + /* + * Check for the facility that need to be emulated + */ + ulong fscr_ic = vcpu->arch.shadow_fscr >> 56; + if (fscr_ic != FSCR_EBB_LG) { + /* + * We only disable EBB facility. + * So only emulate that. + */ + kvmppc_book3s_queue_irqprio(vcpu, exit_nr); + r = RESUME_GUEST; + break; + } + /* Fall through */ + } case BOOK3S_INTERRUPT_PROGRAM: case BOOK3S_INTERRUPT_H_EMUL_ASSIST: {
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:39
We allow priv-mode update of this. The guest value is saved in fscr, and the value actually used is saved in shadow_fscr. shadow_fscr only contains values that are allowed by the host. On facility unavailable interrupt, if the facility is allowed by fscr but disabled in shadow_fscr we need to emulate the support. Currently all but EBB is disabled. We still don't support performance monitoring in PR guest. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_book3s_asm.h | 1 + arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kernel/asm-offsets.c | 2 ++ arch/powerpc/kvm/book3s_emulate.c | 16 ++++++++++++++++ arch/powerpc/kvm/book3s_interrupts.S | 25 ++++++++++++++++++++++--- 5 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h
index 192917d2239c..abd42523ad93 100644
--- a/arch/powerpc/include/asm/kvm_book3s_asm.h
+++ b/arch/powerpc/include/asm/kvm_book3s_asm.h@@ -103,6 +103,7 @@ struct kvmppc_host_state { #ifdef CONFIG_PPC_BOOK3S_64 u64 cfar; u64 ppr; + u64 host_fscr; #endif };
diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
index e0b13aca98e6..f4be7be14330 100644
--- a/arch/powerpc/include/asm/kvm_host.h
+++ b/arch/powerpc/include/asm/kvm_host.h@@ -478,6 +478,7 @@ struct kvm_vcpu_arch { ulong ppr; ulong pspb; ulong fscr; + ulong shadow_fscr; ulong tfhar; ulong tfiar; ulong texasr;
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 2c2227da6917..7484676b8f25 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c@@ -525,6 +525,7 @@ int main(void) DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr)); DEFINE(VCPU_FSCR, offsetof(struct kvm_vcpu, arch.fscr)); + DEFINE(VCPU_SHADOW_FSCR, offsetof(struct kvm_vcpu, arch.shadow_fscr)); DEFINE(VCPU_PSPB, offsetof(struct kvm_vcpu, arch.pspb)); DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar)); DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));
@@ -626,6 +627,7 @@ int main(void) #ifdef CONFIG_PPC_BOOK3S_64 HSTATE_FIELD(HSTATE_CFAR, cfar); HSTATE_FIELD(HSTATE_PPR, ppr); + HSTATE_FIELD(HSTATE_FSCR, host_fscr); #endif /* CONFIG_PPC_BOOK3S_64 */ #else /* CONFIG_PPC_BOOK3S */
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index 7f25adbd2590..60d0b6b745e7 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -468,6 +468,19 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_MSSSR0: case SPRN_DABR: break; + case SPRN_FSCR: + { + ulong host_fscr = mfspr(SPRN_FSCR); + /* + * We disable FSCR_EBB for pr guest. TAR and DSCR are always + * enabled. + */ + if (spr_val & ~(FSCR_TAR|FSCR_DSCR|FSCR_EBB)) + pr_info("KVM: invalud FSCR value 0x%lx", spr_val); + vcpu->arch.fscr = spr_val & (FSCR_TAR|FSCR_DSCR); + vcpu->arch.shadow_fscr = vcpu->arch.fscr & host_fscr; + break; + } unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
@@ -591,6 +604,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val */ *spr_val = 0; break; + case SPRN_FSCR: + *spr_val = vcpu->arch.fscr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);
diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S
index f779450cb07c..fcbdf4817301 100644
--- a/arch/powerpc/kvm/book3s_interrupts.S
+++ b/arch/powerpc/kvm/book3s_interrupts.S@@ -107,6 +107,14 @@ kvm_start_lightweight: ld r3, VCPU_SHARED(r4) ld r3, VCPU_SHARED_SPRG3(r3) mtspr SPRN_SPRG3, r3 + +BEGIN_FTR_SECTION + mfspr r3,SPRN_FSCR + PPC_STL r3, HSTATE_FSCR(r13) + + PPC_LL r3, VCPU_SHADOW_FSCR(r4) + mtspr SPRN_FSCR, r3 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) #endif /* CONFIG_PPC_BOOK3S_64 */ PPC_LL r4, VCPU_SHADOW_MSR(r4) /* get shadow_msr */
@@ -148,6 +156,9 @@ kvm_start_lightweight: bl FUNC(kvmppc_copy_from_svcpu) nop + /* R7 = vcpu */ + PPC_LL r7, GPR4(r1) + #ifdef CONFIG_PPC_BOOK3S_64 /* * Reload kernel SPRG3 value.
@@ -155,10 +166,18 @@ kvm_start_lightweight: */ ld r3, PACA_SPRG3(r13) mtspr SPRN_SPRG3, r3 -#endif /* CONFIG_PPC_BOOK3S_64 */ +BEGIN_FTR_SECTION + /* + * Save the current fscr in shadow fscr + */ + mfspr r3,SPRN_FSCR + PPC_STL r3, VCPU_SHADOW_FSCR(r7) - /* R7 = vcpu */ - PPC_LL r7, GPR4(r1) + PPC_LL r3, HSTATE_FSCR(r13) + mtspr SPRN_FSCR, r3 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) + +#endif /* CONFIG_PPC_BOOK3S_64 */ PPC_STL r14, VCPU_GPR(R14)(r7) PPC_STL r15, VCPU_GPR(R15)(r7)
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:40
We ignore write to these registers now Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/kvm/book3s_emulate.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index bf6b11021250..c0aee34ef04f 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c@@ -490,6 +490,16 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_BESCR: vcpu->arch.bescr = spr_val; break; + case SPRN_MMCRS: + break; + case SPRN_MMCRA: + break; + case SPRN_MMCR0: + break; + case SPRN_MMCR1: + break; + case SPRN_MMCR2: + break; unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);
--
1.8.5.3
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-28 16:44:42
Runtime disable transactional memory feature looking at pa-features device tree entry. We need to do this so that we can run a kernel built with TM config in PR mode. For PR guest we provide a device tree entry with TM feature disabled in pa-features Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/kernel/prom.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index fa0ad8aafbcc..de8c2caf1024 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c@@ -160,6 +160,11 @@ static struct ibm_pa_feature { {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, + /* + * We should use CPU_FTR_TM_COMP so that if we disable TM, it won't get + * enabled via device tree + */ + {CPU_FTR_TM_COMP, 0, 0, 22, 0, 0}, }; static void __init scan_features(unsigned long node, unsigned char *ftrs,
--
1.8.5.3
From: Alexander Graf <hidden>
Date: 2014-01-29 16:32:27
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
We definitely don't need to emulate mtspr, because both the registers are hypervisor resource.
This patch description doesn't cover what the patch actually does. It changes the implementation from "always tell the guest it uses 100%" to "give the guest an accurate amount of cpu time spent inside guest context". Also, I think we either go with full hyp semantics which means we also emulate the offset or we go with no hyp awareness in the guest at all which means we also don't emulate SPURR which is a hyp privileged register. Otherwise I like the patch :). Alex
Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_book3s.h | 2 -- arch/powerpc/include/asm/kvm_host.h | 4 ++-- arch/powerpc/kvm/book3s_emulate.c | 16 ++++++++-------- arch/powerpc/kvm/book3s_pr.c | 10 ++++++++++ 4 files changed, 20 insertions(+), 12 deletions(-)diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h index bc23b1ba7980..396448afa38b 100644 --- a/arch/powerpc/include/asm/kvm_book3s.h +++ b/arch/powerpc/include/asm/kvm_book3s.h@@ -83,8 +83,6 @@ 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;diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9a0cdb2c9d58..0a3785271f34 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -506,8 +506,8 @@ struct kvm_vcpu_arch { #ifdef CONFIG_BOOKE u32 decar; #endif - u32 tbl; - u32 tbu; + /* Time base value when we entered the guest */ + u64 entry_tb; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index a7d54aa203d0..e1f1e5e16449 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -422,12 +422,6 @@ int kvmppc_core_emulate_mtspr_pr(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:@@ -523,10 +517,16 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val *spr_val = 0; break; case SPRN_PURR: - *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; + /* + * On exit we would have updated purr + */ + *spr_val = vcpu->arch.purr; break; case SPRN_SPURR: - *spr_val = get_tb() + to_book3s(vcpu)->purr_offset; + /* + * On exit we would have updated spurr + */ + *spr_val = vcpu->arch.spurr; break; case SPRN_GQR0: case SPRN_GQR1:diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index fdcbabdfb709..02231f5193c2 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -115,6 +115,11 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, svcpu->lr = vcpu->arch.lr; svcpu->pc = vcpu->arch.pc; svcpu->in_use = true; + /* + * Now also save the current time base value. We use this + * to find the guest purr and spurr value. + */ + vcpu->arch.entry_tb = get_tb(); } /* Copy data touched by real-mode code from shadow vcpu back to vcpu */@@ -161,6 +166,11 @@ void kvmppc_copy_from_svcpu(struct kvm_vcpu *vcpu, out: preempt_enable(); + /* + * Update purr and spurr using time base + */ + vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; + vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; } static int kvmppc_core_check_requests_pr(struct kvm_vcpu *vcpu)
From: Alexander Graf <hidden>
Date: 2014-01-29 16:39:39
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
virtual time base register is a per vm register and need to saved and restored on vm exit and entry. Writing to VTB is not allowed in the privileged mode. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/reg.h | 7 +++++++ arch/powerpc/include/asm/time.h | 12 ++++++++++++ arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 3 +++ 5 files changed, 26 insertions(+)diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 0a3785271f34..9ebdd12e50a9 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -508,6 +508,7 @@ struct kvm_vcpu_arch { #endif /* Time base value when we entered the guest */ u64 entry_tb; + u64 entry_vtb; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index e789f76c9bc2..6c649355b1e9 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h@@ -1161,6 +1161,13 @@ #define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ : "r" ((unsigned long)(v)) \ : "memory") +#ifdef CONFIG_PPC_BOOK3S_64 +#define mfvtb() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : \ + "=r" (rval) : "i" (SPRN_VTB)); rval;}) +#else +#define mfvtb() BUG() +#endif
static inline mfvtb(unsigned long)
{
#ifdef CONFIG_PPC_BOOK3S_64
return mfspr(SPRN_VTB);
#else
BUG();
#endif
}
is a lot easier to read and get right. But reg.h is Ben's call.
Also could you please give me a pointer to the specification for it? I
tried to look up vtb in the 2.06 ISA and couldn't find it. Is it a CPU
specific register?
#ifdef __powerpc64__ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E)diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index c1f267694acb..1e89dbc665d9 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h@@ -101,6 +101,18 @@ static inline u64 get_rtc(void) return (u64)hi * 1000000000 + lo; } +#ifdef CONFIG_PPC_BOOK3S_64 +static inline u64 get_vtb(void) +{ + return mfvtb(); +} +#else +static inline u64 get_vtb(void) +{ + return 0; +} +#endif
Just put the #ifdef inside the function body.
+ #ifdef CONFIG_PPC64 static inline u64 get_tb(void) {diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index e1f1e5e16449..4b58d8a90cb5 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -528,6 +528,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val */ *spr_val = vcpu->arch.spurr; break; + case SPRN_VTB: + *spr_val = vcpu->arch.vtb; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 02231f5193c2..b5598e9cdd09 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -120,6 +120,8 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, * to find the guest purr and spurr value. */ vcpu->arch.entry_tb = get_tb(); + vcpu->arch.entry_vtb = get_vtb(); + } /* Copy data touched by real-mode code from shadow vcpu back to vcpu */@@ -171,6 +173,7 @@ out: */ vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; + vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb;
I thought it's per vm? That would contradict the per-vcpu logic you're implementing here. This way vtb scews with world switches on SMP guests. Alex
From: Alexander Graf <hidden>
Date: 2014-01-29 16:40:45
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
Writing to IC is not allowed in the privileged mode.
This is not a patch description.
Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 2 ++ 3 files changed, 6 insertions(+)diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9ebdd12e50a9..e0b13aca98e6 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -509,6 +509,7 @@ struct kvm_vcpu_arch { /* Time base value when we entered the guest */ u64 entry_tb; u64 entry_vtb; + u64 entry_ic; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 4b58d8a90cb5..abe6f3057e5b 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -531,6 +531,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_VTB: *spr_val = vcpu->arch.vtb; break; + case SPRN_IC: + *spr_val = vcpu->arch.ic; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index b5598e9cdd09..51d469f8c9fd 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -121,6 +121,7 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, */ vcpu->arch.entry_tb = get_tb(); vcpu->arch.entry_vtb = get_vtb(); + vcpu->arch.entry_ic = mfspr(SPRN_IC);
Is this implemented on all systems?
}@@ -174,6 +175,7 @@ out: vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; + vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic;
This is getting quite convoluted. How about we act slightly more fuzzy and put all of this into vcpu_load/put? Alex
From: Alexander Graf <hidden>
Date: 2014-01-29 17:11:42
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
We allow priv-mode update of this. The guest value is saved in fscr, and the value actually used is saved in shadow_fscr. shadow_fscr only contains values that are allowed by the host. On facility unavailable interrupt, if the facility is allowed by fscr but disabled in shadow_fscr we need to emulate the support. Currently all but EBB is disabled. We still don't support performance monitoring in PR guest. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_book3s_asm.h | 1 + arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kernel/asm-offsets.c | 2 ++ arch/powerpc/kvm/book3s_emulate.c | 16 ++++++++++++++++ arch/powerpc/kvm/book3s_interrupts.S | 25 ++++++++++++++++++++++--- 5 files changed, 42 insertions(+), 3 deletions(-)diff --git a/arch/powerpc/include/asm/kvm_book3s_asm.h b/arch/powerpc/include/asm/kvm_book3s_asm.h index 192917d2239c..abd42523ad93 100644 --- a/arch/powerpc/include/asm/kvm_book3s_asm.h +++ b/arch/powerpc/include/asm/kvm_book3s_asm.h@@ -103,6 +103,7 @@ struct kvmppc_host_state { #ifdef CONFIG_PPC_BOOK3S_64 u64 cfar; u64 ppr; + u64 host_fscr; #endif };diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index e0b13aca98e6..f4be7be14330 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -478,6 +478,7 @@ struct kvm_vcpu_arch { ulong ppr; ulong pspb; ulong fscr; + ulong shadow_fscr; ulong tfhar; ulong tfiar; ulong texasr;diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 2c2227da6917..7484676b8f25 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c@@ -525,6 +525,7 @@ int main(void) DEFINE(VCPU_CFAR, offsetof(struct kvm_vcpu, arch.cfar)); DEFINE(VCPU_PPR, offsetof(struct kvm_vcpu, arch.ppr)); DEFINE(VCPU_FSCR, offsetof(struct kvm_vcpu, arch.fscr)); + DEFINE(VCPU_SHADOW_FSCR, offsetof(struct kvm_vcpu, arch.shadow_fscr)); DEFINE(VCPU_PSPB, offsetof(struct kvm_vcpu, arch.pspb)); DEFINE(VCPU_TFHAR, offsetof(struct kvm_vcpu, arch.tfhar)); DEFINE(VCPU_TFIAR, offsetof(struct kvm_vcpu, arch.tfiar));@@ -626,6 +627,7 @@ int main(void) #ifdef CONFIG_PPC_BOOK3S_64 HSTATE_FIELD(HSTATE_CFAR, cfar); HSTATE_FIELD(HSTATE_PPR, ppr); + HSTATE_FIELD(HSTATE_FSCR, host_fscr); #endif /* CONFIG_PPC_BOOK3S_64 */ #else /* CONFIG_PPC_BOOK3S */diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 7f25adbd2590..60d0b6b745e7 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -468,6 +468,19 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) case SPRN_MSSSR0: case SPRN_DABR: break; + case SPRN_FSCR: + { + ulong host_fscr = mfspr(SPRN_FSCR); + /* + * We disable FSCR_EBB for pr guest. TAR and DSCR are always + * enabled. + */ + if (spr_val & ~(FSCR_TAR|FSCR_DSCR|FSCR_EBB)) + pr_info("KVM: invalud FSCR value 0x%lx", spr_val);
Is this worth printing at all? If it is, it's probably more of a pr_debug(). Also s/invalud/invalid/. Alex
+ vcpu->arch.fscr = spr_val & (FSCR_TAR|FSCR_DSCR); + vcpu->arch.shadow_fscr = vcpu->arch.fscr & host_fscr; + break; + } unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);@@ -591,6 +604,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val */ *spr_val = 0; break; + case SPRN_FSCR: + *spr_val = vcpu->arch.fscr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);diff --git a/arch/powerpc/kvm/book3s_interrupts.S b/arch/powerpc/kvm/book3s_interrupts.S index f779450cb07c..fcbdf4817301 100644 --- a/arch/powerpc/kvm/book3s_interrupts.S +++ b/arch/powerpc/kvm/book3s_interrupts.S@@ -107,6 +107,14 @@ kvm_start_lightweight: ld r3, VCPU_SHARED(r4) ld r3, VCPU_SHARED_SPRG3(r3) mtspr SPRN_SPRG3, r3 + +BEGIN_FTR_SECTION + mfspr r3,SPRN_FSCR + PPC_STL r3, HSTATE_FSCR(r13) + + PPC_LL r3, VCPU_SHADOW_FSCR(r4) + mtspr SPRN_FSCR, r3 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) #endif /* CONFIG_PPC_BOOK3S_64 */ PPC_LL r4, VCPU_SHADOW_MSR(r4) /* get shadow_msr */@@ -148,6 +156,9 @@ kvm_start_lightweight: bl FUNC(kvmppc_copy_from_svcpu) nop + /* R7 = vcpu */ + PPC_LL r7, GPR4(r1) + #ifdef CONFIG_PPC_BOOK3S_64 /* * Reload kernel SPRG3 value.@@ -155,10 +166,18 @@ kvm_start_lightweight: */ ld r3, PACA_SPRG3(r13) mtspr SPRN_SPRG3, r3 -#endif /* CONFIG_PPC_BOOK3S_64 */ +BEGIN_FTR_SECTION + /* + * Save the current fscr in shadow fscr + */ + mfspr r3,SPRN_FSCR + PPC_STL r3, VCPU_SHADOW_FSCR(r7) - /* R7 = vcpu */ - PPC_LL r7, GPR4(r1) + PPC_LL r3, HSTATE_FSCR(r13) + mtspr SPRN_FSCR, r3 +END_FTR_SECTION_IFSET(CPU_FTR_ARCH_207S) + +#endif /* CONFIG_PPC_BOOK3S_64 */ PPC_STL r14, VCPU_GPR(R14)(r7) PPC_STL r15, VCPU_GPR(R15)(r7)
From: Alexander Graf <hidden>
Date: 2014-01-29 17:35:52
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
At this point we allow all the supported facilities except EBB. So forward the interrupt to guest as illegal instruction. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_asm.h | 4 +++- arch/powerpc/kvm/book3s.c | 4 ++++ arch/powerpc/kvm/book3s_emulate.c | 18 ++++++++++++++++++ arch/powerpc/kvm/book3s_pr.c | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-)diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 1bd92fd43cfb..799244face51 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h@@ -99,6 +99,7 @@ #define BOOK3S_INTERRUPT_PERFMON 0xf00 #define BOOK3S_INTERRUPT_ALTIVEC 0xf20 #define BOOK3S_INTERRUPT_VSX 0xf40 +#define BOOK3S_INTERRUPT_FAC_UNAVAIL 0xf60 #define BOOK3S_IRQPRIO_SYSTEM_RESET 0 #define BOOK3S_IRQPRIO_DATA_SEGMENT 1@@ -117,7 +118,8 @@ #define BOOK3S_IRQPRIO_DECREMENTER 14 #define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15 #define BOOK3S_IRQPRIO_EXTERNAL_LEVEL 16 -#define BOOK3S_IRQPRIO_MAX 17 +#define BOOK3S_IRQPRIO_FAC_UNAVAIL 17 +#define BOOK3S_IRQPRIO_MAX 18 #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 8912608b7e1b..a9aea28c2677 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c@@ -143,6 +143,7 @@ static int kvmppc_book3s_vec2irqprio(unsigned int vec) case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break; case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break; case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break; + case 0xf60: prio = BOOK3S_IRQPRIO_FAC_UNAVAIL; break; default: prio = BOOK3S_IRQPRIO_MAX; break; }@@ -273,6 +274,9 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR: vec = BOOK3S_INTERRUPT_PERFMON; break; + case BOOK3S_IRQPRIO_FAC_UNAVAIL: + vec = BOOK3S_INTERRUPT_FAC_UNAVAIL; + break; default: deliver = 0; printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 60d0b6b745e7..bf6b11021250 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -481,6 +481,15 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) vcpu->arch.shadow_fscr = vcpu->arch.fscr & host_fscr; break; } + case SPRN_EBBHR: + vcpu->arch.ebbhr = spr_val; + break; + case SPRN_EBBRR: + vcpu->arch.ebbrr = spr_val; + break; + case SPRN_BESCR: + vcpu->arch.bescr = spr_val; + break; unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);@@ -607,6 +616,15 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_FSCR: *spr_val = vcpu->arch.fscr; break; + case SPRN_EBBHR: + *spr_val = vcpu->arch.ebbhr; + break; + case SPRN_EBBRR: + *spr_val = vcpu->arch.ebbrr; + break; + case SPRN_BESCR: + *spr_val = vcpu->arch.bescr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 51d469f8c9fd..828056ec208f 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -900,6 +900,23 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_PERFMON: r = RESUME_GUEST; break; + case BOOK3S_INTERRUPT_FAC_UNAVAIL: + { + /* + * Check for the facility that need to be emulated + */ + ulong fscr_ic = vcpu->arch.shadow_fscr >> 56; + if (fscr_ic != FSCR_EBB_LG) { + /* + * We only disable EBB facility. + * So only emulate that.
I don't understand the comment. We emulate nothing at all here. We either
- hit an EBB unavailable in which case we send the guest an illegal
instruction interrupt or we
- hit another facility interrupt in which case we forward the
interrupt to the guest, but not the interrupt cause (fscr_ic).
I think the EBB case should be explicit:
/* We don't allow EBB inside the guest, so something must have gone
terribly wrong */
if (fscr_ic == FSCR_EBB_LG)
BUG();
vcpu->arch.fscr &= ~FSCR_IC_MASK;
vcpu->arch.fscr |= vcpu->arch.shadow_fscr & FSCR_IC_MASK;
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
r = RESUME_GUEST;
break;
Alex
+ */
+ kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
+ r = RESUME_GUEST;
+ break;
+ }
+ /* Fall through */
+ }
case BOOK3S_INTERRUPT_PROGRAM:
case BOOK3S_INTERRUPT_H_EMUL_ASSIST:
{
From: Alexander Graf <hidden>
Date: 2014-01-29 17:37:22
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:
Runtime disable transactional memory feature looking at pa-features device tree entry. We need to do this so that we can run a kernel built with TM config in PR mode. For PR guest we provide a device tree entry with TM feature disabled in pa-features Signed-off-by: Aneesh Kumar K.V <redacted>
We need to be able to run kernels without this patch, so better fix TM for good - worst case by always aborting transactions. Alex
--- arch/powerpc/kernel/prom.c | 5 +++++ 1 file changed, 5 insertions(+)diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index fa0ad8aafbcc..de8c2caf1024 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c@@ -160,6 +160,11 @@ static struct ibm_pa_feature { {CPU_FTR_NODSISRALIGN, 0, 0, 1, 1, 1}, {0, MMU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, + /* + * We should use CPU_FTR_TM_COMP so that if we disable TM, it won't get + * enabled via device tree + */ + {CPU_FTR_TM_COMP, 0, 0, 22, 0, 0}, }; static void __init scan_features(unsigned long node, unsigned char *ftrs,
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2014-01-29 22:54:52
On Wed, 2014-01-29 at 17:39 +0100, Alexander Graf wrote:
static inline mfvtb(unsigned long)
{
#ifdef CONFIG_PPC_BOOK3S_64
return mfspr(SPRN_VTB);
#else
BUG();
#endif
}
is a lot easier to read and get right. But reg.h is Ben's call.Agreed.
Also could you please give me a pointer to the specification for it? I tried to look up vtb in the 2.06 ISA and couldn't find it. Is it a CPU specific register?
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: 2014-01-30 00:35:27
On Thu, 2014-01-30 at 09:54 +1100, Benjamin Herrenschmidt wrote:
On Wed, 2014-01-29 at 17:39 +0100, Alexander Graf wrote:quoted
static inline mfvtb(unsigned long) { #ifdef CONFIG_PPC_BOOK3S_64 return mfspr(SPRN_VTB); #else BUG(); #endif } is a lot easier to read and get right. But reg.h is Ben's call.Agreed.
I mean I agree with Alex, his version is nicer :-) Cheers, Ben.
From: Paul Mackerras <hidden>
Date: 2014-01-30 05:49:13
On Tue, Jan 28, 2014 at 10:14:07PM +0530, Aneesh Kumar K.V wrote:
virtual time base register is a per vm register and need to saved and restored on vm exit and entry. Writing to VTB is not allowed in the privileged mode.
...
+#ifdef CONFIG_PPC_BOOK3S_64
+#define mfvtb() ({unsigned long rval; \
+ asm volatile("mfspr %0, %1" : \
+ "=r" (rval) : "i" (SPRN_VTB)); rval;})The mfspr will be a no-op on anything before POWER8, meaning the result will be whatever value was in the destination GPR before the mfspr. I suppose that may not matter if the result is only ever used when we're running on a POWER8 host, but I would feel more comfortable if we had explicit feature tests to make sure of that, rather than possibly doing computations with unpredictable values. With your patch, a guest on a POWER7 or a PPC970 could do a read from VTB and get garbage -- first, there is nothing to stop userspace from requesting POWER8 emulation on an older machine, and secondly, even if the virtual machine is a PPC970 (say) you don't implement unimplemented SPR semantics for VTB (no-op if PR=0, illegal instruction interrupt if PR=1). On the whole I think it is reasonable to reject an attempt to set the virtual PVR to a POWER8 PVR value if we are not running on a POWER8 host, because emulating all the new POWER8 features in software (particularly transactional memory) would not be feasible. Alex may disagree. :) Paul.
From: Paul Mackerras <hidden>
Date: 2014-01-30 06:00:00
On Tue, Jan 28, 2014 at 10:14:12PM +0530, Aneesh Kumar K.V wrote:
We allow priv-mode update of this. The guest value is saved in fscr, and the value actually used is saved in shadow_fscr. shadow_fscr only contains values that are allowed by the host. On facility unavailable interrupt, if the facility is allowed by fscr but disabled in shadow_fscr we need to emulate the support. Currently all but EBB is disabled. We still don't support performance monitoring in PR guest.
...
+ /* + * Save the current fscr in shadow fscr + */ + mfspr r3,SPRN_FSCR + PPC_STL r3, VCPU_SHADOW_FSCR(r7)
I don't think you need to do this. What could possibly have changed FSCR since we loaded it on the way into the guest? Paul.
From: Alexander Graf <hidden>
Date: 2014-01-30 10:02:13
Am 30.01.2014 um 07:00 schrieb Paul Mackerras [off-list ref]: =20quoted
On Tue, Jan 28, 2014 at 10:14:12PM +0530, Aneesh Kumar K.V wrote: We allow priv-mode update of this. The guest value is saved in fscr, and the value actually used is saved in shadow_fscr. shadow_fscr only contains values that are allowed by the host. On facility unavailable interrupt, if the facility is allowed by fscr but disabled in shadow_fscr we need to emulate the support. Currently all but EBB is disabled. We still don't support performance monitoring in PR guest.=20 ... =20quoted
+ /* + * Save the current fscr in shadow fscr + */ + mfspr r3,SPRN_FSCR + PPC_STL r3, VCPU_SHADOW_FSCR(r7)=20 I don't think you need to do this. What could possibly have changed FSCR since we loaded it on the way into the guest?
The interrupt cause is part of fscr. But yes, we only meed to store that on a= n fscr interrupt. Do we use anything from fscr inside the kernel? Could we switch it lazily on= vcpu_load/put? Alex
=20 Paul.
From: Alexander Graf <hidden>
Date: 2014-01-30 10:04:51
Am 30.01.2014 um 06:49 schrieb Paul Mackerras [off-list ref]: =20quoted
On Tue, Jan 28, 2014 at 10:14:07PM +0530, Aneesh Kumar K.V wrote: virtual time base register is a per vm register and need to saved and restored on vm exit and entry. Writing to VTB is not allowed in the privileged mode.... =20quoted
+#ifdef CONFIG_PPC_BOOK3S_64 +#define mfvtb() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : \ + "=3Dr" (rval) : "i" (SPRN_VTB)); rval;})=20 The mfspr will be a no-op on anything before POWER8, meaning the result will be whatever value was in the destination GPR before the mfspr. I suppose that may not matter if the result is only ever used when we're running on a POWER8 host, but I would feel more comfortable if we had explicit feature tests to make sure of that, rather than possibly doing computations with unpredictable values. =20 With your patch, a guest on a POWER7 or a PPC970 could do a read from VTB and get garbage -- first, there is nothing to stop userspace from requesting POWER8 emulation on an older machine, and secondly, even if the virtual machine is a PPC970 (say) you don't implement unimplemented SPR semantics for VTB (no-op if PR=3D0, illegal instruction interrupt if PR=3D1). =20 On the whole I think it is reasonable to reject an attempt to set the virtual PVR to a POWER8 PVR value if we are not running on a POWER8 host, because emulating all the new POWER8 features in software (particularly transactional memory) would not be feasible. Alex may disagree. :)
We don't have a good feature flag indicator that tells kvm what the guest cp= u is capable of. So yes, I think it's reasonable to just not expose p8 regis= ters on p8 for now. In theory it's of course possible to emulate a lot of p8 features on pre-p8 h= ardware, but I'm not sure it's worth the effort. If anyone wants to spend th= e time to work on it I'd be happy to tale patches though ;) Alex
=20 Paul.
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-31 10:39:05
Alexander Graf [off-list ref] writes:
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
We definitely don't need to emulate mtspr, because both the registers are hypervisor resource.This patch description doesn't cover what the patch actually does. It changes the implementation from "always tell the guest it uses 100%" to "give the guest an accurate amount of cpu time spent inside guest context".
Will fix that
Also, I think we either go with full hyp semantics which means we also emulate the offset or we go with no hyp awareness in the guest at all which means we also don't emulate SPURR which is a hyp privileged register.
Can you clarify this ?
Otherwise I like the patch :).
-aneesh
From: Alexander Graf <hidden>
Date: 2014-01-31 10:47:48
On 31.01.2014, at 11:38, Aneesh Kumar K.V = [off-list ref] wrote:
Alexander Graf [off-list ref] writes: =20quoted
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
We definitely don't need to emulate mtspr, because both the =
registers
quoted
quoted
are hypervisor resource.=20 This patch description doesn't cover what the patch actually does. It=20=
quoted
changes the implementation from "always tell the guest it uses 100%" =
to=20
quoted
"give the guest an accurate amount of cpu time spent inside guest context".=20 Will fix that =20quoted
=20 Also, I think we either go with full hyp semantics which means we =
also=20
quoted
emulate the offset or we go with no hyp awareness in the guest at all=20=
quoted
which means we also don't emulate SPURR which is a hyp privileged register.=20 Can you clarify this ?
In the 2.06 ISA SPURR is hypervisor privileged. That changed for 2.07 = where it became supervisor privileged. So I suppose your patch is ok. = When reviewing those patches I only had 2.06 around because power.org = was broken. Alex
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-31 10:57:43
Paul Mackerras [off-list ref] writes:
On Tue, Jan 28, 2014 at 10:14:07PM +0530, Aneesh Kumar K.V wrote:quoted
virtual time base register is a per vm register and need to saved and restored on vm exit and entry. Writing to VTB is not allowed in the privileged mode....quoted
+#ifdef CONFIG_PPC_BOOK3S_64 +#define mfvtb() ({unsigned long rval; \ + asm volatile("mfspr %0, %1" : \ + "=r" (rval) : "i" (SPRN_VTB)); rval;})The mfspr will be a no-op on anything before POWER8, meaning the result will be whatever value was in the destination GPR before the mfspr. I suppose that may not matter if the result is only ever used when we're running on a POWER8 host, but I would feel more comfortable if we had explicit feature tests to make sure of that, rather than possibly doing computations with unpredictable values. With your patch, a guest on a POWER7 or a PPC970 could do a read from VTB and get garbage -- first, there is nothing to stop userspace from requesting POWER8 emulation on an older machine, and secondly, even if the virtual machine is a PPC970 (say) you don't implement unimplemented SPR semantics for VTB (no-op if PR=0, illegal instruction interrupt if PR=1).
Ok that means we need to do something like ?
struct cpu_spec *s = find_cpuspec(vcpu->arch.pvr);
if (s->cpu_features & CPU_FTR_ARCH_207S) {
}
On the whole I think it is reasonable to reject an attempt to set the virtual PVR to a POWER8 PVR value if we are not running on a POWER8 host, because emulating all the new POWER8 features in software (particularly transactional memory) would not be feasible. Alex may disagree. :)
That would make it much simpler. -aneesh
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-31 11:26:05
Alexander Graf [off-list ref] writes:
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
Writing to IC is not allowed in the privileged mode.This is not a patch description.quoted
Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 2 ++ 3 files changed, 6 insertions(+)diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 9ebdd12e50a9..e0b13aca98e6 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -509,6 +509,7 @@ struct kvm_vcpu_arch { /* Time base value when we entered the guest */ u64 entry_tb; u64 entry_vtb; + u64 entry_ic; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires ulong */ u32 ivor[64];diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 4b58d8a90cb5..abe6f3057e5b 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -531,6 +531,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_VTB: *spr_val = vcpu->arch.vtb; break; + case SPRN_IC: + *spr_val = vcpu->arch.ic; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index b5598e9cdd09..51d469f8c9fd 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -121,6 +121,7 @@ void kvmppc_copy_to_svcpu(struct kvmppc_book3s_shadow_vcpu *svcpu, */ vcpu->arch.entry_tb = get_tb(); vcpu->arch.entry_vtb = get_vtb(); + vcpu->arch.entry_ic = mfspr(SPRN_IC);Is this implemented on all systems?quoted
}@@ -174,6 +175,7 @@ out: vcpu->arch.purr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr += get_tb() - vcpu->arch.entry_tb; vcpu->arch.vtb += get_vtb() - vcpu->arch.entry_vtb; + vcpu->arch.ic += mfspr(SPRN_IC) - vcpu->arch.entry_ic;This is getting quite convoluted. How about we act slightly more fuzzy and put all of this into vcpu_load/put?
I am not sure whether vcpu_load/put is too early/late to save these context ? -aneesh
From: Alexander Graf <hidden>
Date: 2014-01-31 11:28:11
On 31.01.2014, at 12:25, Aneesh Kumar K.V = [off-list ref] wrote:
Alexander Graf [off-list ref] writes: =20quoted
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
Writing to IC is not allowed in the privileged mode.=20 This is not a patch description. =20quoted
=20 Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_pr.c | 2 ++ 3 files changed, 6 insertions(+) =20diff --git a/arch/powerpc/include/asm/kvm_host.h =
b/arch/powerpc/include/asm/kvm_host.h
quoted
quoted
index 9ebdd12e50a9..e0b13aca98e6 100644--- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h@@ -509,6 +509,7 @@ struct kvm_vcpu_arch { /* Time base value when we entered the guest */ u64 entry_tb; u64 entry_vtb; + u64 entry_ic; u32 tcr; ulong tsr; /* we need to perform set/clr_bits() which requires =
ulong */
quoted
quoted
u32 ivor[64];diff --git a/arch/powerpc/kvm/book3s_emulate.c =
b/arch/powerpc/kvm/book3s_emulate.c
quoted
quoted
index 4b58d8a90cb5..abe6f3057e5b 100644--- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -531,6 +531,9 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu =
*vcpu, int sprn, ulong *spr_val
quoted
quoted
case SPRN_VTB: *spr_val =3D vcpu->arch.vtb; break; + case SPRN_IC: + *spr_val =3D vcpu->arch.ic; + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2:diff --git a/arch/powerpc/kvm/book3s_pr.c =
b/arch/powerpc/kvm/book3s_pr.c
quoted
quoted
index b5598e9cdd09..51d469f8c9fd 100644--- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -121,6 +121,7 @@ void kvmppc_copy_to_svcpu(struct =
kvmppc_book3s_shadow_vcpu *svcpu,
quoted
quoted
*/ vcpu->arch.entry_tb =3D get_tb(); vcpu->arch.entry_vtb =3D get_vtb(); + vcpu->arch.entry_ic =3D mfspr(SPRN_IC);=20 Is this implemented on all systems? =20quoted
=20 } =20@@ -174,6 +175,7 @@ out: vcpu->arch.purr +=3D get_tb() - vcpu->arch.entry_tb; vcpu->arch.spurr +=3D get_tb() - vcpu->arch.entry_tb; vcpu->arch.vtb +=3D get_vtb() - vcpu->arch.entry_vtb; + vcpu->arch.ic +=3D mfspr(SPRN_IC) - vcpu->arch.entry_ic;=20 This is getting quite convoluted. How about we act slightly more =
fuzzy=20
quoted
and put all of this into vcpu_load/put? =20=20 I am not sure whether vcpu_load/put is too early/late to save these context ?
It'd mean we treat instruction emulation as part of guest overhead and = time, but we'd make the entry/exit path faster. Unlike with HV KVM, = guest entry/exit is pretty hot due to the massive amounts of instruction = emulation we need to do. Alex
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-31 11:28:14
Paul Mackerras [off-list ref] writes:
On Tue, Jan 28, 2014 at 10:14:12PM +0530, Aneesh Kumar K.V wrote:quoted
We allow priv-mode update of this. The guest value is saved in fscr, and the value actually used is saved in shadow_fscr. shadow_fscr only contains values that are allowed by the host. On facility unavailable interrupt, if the facility is allowed by fscr but disabled in shadow_fscr we need to emulate the support. Currently all but EBB is disabled. We still don't support performance monitoring in PR guest....quoted
+ /* + * Save the current fscr in shadow fscr + */ + mfspr r3,SPRN_FSCR + PPC_STL r3, VCPU_SHADOW_FSCR(r7)I don't think you need to do this. What could possibly have changed FSCR since we loaded it on the way into the guest?
The reason for facility unavailable interrupt is encoded in FSCR right ? -aneesh
From: Aneesh Kumar K.V <hidden>
Date: 2014-01-31 11:40:30
Alexander Graf [off-list ref] writes:
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
At this point we allow all the supported facilities except EBB. So forward the interrupt to guest as illegal instruction. Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_asm.h | 4 +++- arch/powerpc/kvm/book3s.c | 4 ++++ arch/powerpc/kvm/book3s_emulate.c | 18 ++++++++++++++++++ arch/powerpc/kvm/book3s_pr.c | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-)diff --git a/arch/powerpc/include/asm/kvm_asm.h b/arch/powerpc/include/asm/kvm_asm.h index 1bd92fd43cfb..799244face51 100644 --- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h@@ -99,6 +99,7 @@ #define BOOK3S_INTERRUPT_PERFMON 0xf00 #define BOOK3S_INTERRUPT_ALTIVEC 0xf20 #define BOOK3S_INTERRUPT_VSX 0xf40 +#define BOOK3S_INTERRUPT_FAC_UNAVAIL 0xf60 #define BOOK3S_IRQPRIO_SYSTEM_RESET 0 #define BOOK3S_IRQPRIO_DATA_SEGMENT 1@@ -117,7 +118,8 @@ #define BOOK3S_IRQPRIO_DECREMENTER 14 #define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15 #define BOOK3S_IRQPRIO_EXTERNAL_LEVEL 16 -#define BOOK3S_IRQPRIO_MAX 17 +#define BOOK3S_IRQPRIO_FAC_UNAVAIL 17 +#define BOOK3S_IRQPRIO_MAX 18 #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 8912608b7e1b..a9aea28c2677 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c@@ -143,6 +143,7 @@ static int kvmppc_book3s_vec2irqprio(unsigned int vec) case 0xd00: prio = BOOK3S_IRQPRIO_DEBUG; break; case 0xf20: prio = BOOK3S_IRQPRIO_ALTIVEC; break; case 0xf40: prio = BOOK3S_IRQPRIO_VSX; break; + case 0xf60: prio = BOOK3S_IRQPRIO_FAC_UNAVAIL; break; default: prio = BOOK3S_IRQPRIO_MAX; break; }@@ -273,6 +274,9 @@ int kvmppc_book3s_irqprio_deliver(struct kvm_vcpu *vcpu, unsigned int priority) case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR: vec = BOOK3S_INTERRUPT_PERFMON; break; + case BOOK3S_IRQPRIO_FAC_UNAVAIL: + vec = BOOK3S_INTERRUPT_FAC_UNAVAIL; + break; default: deliver = 0; printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", priority);diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 60d0b6b745e7..bf6b11021250 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -481,6 +481,15 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val) vcpu->arch.shadow_fscr = vcpu->arch.fscr & host_fscr; break; } + case SPRN_EBBHR: + vcpu->arch.ebbhr = spr_val; + break; + case SPRN_EBBRR: + vcpu->arch.ebbrr = spr_val; + break; + case SPRN_BESCR: + vcpu->arch.bescr = spr_val; + break; unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);@@ -607,6 +616,15 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val case SPRN_FSCR: *spr_val = vcpu->arch.fscr; break; + case SPRN_EBBHR: + *spr_val = vcpu->arch.ebbhr; + break; + case SPRN_EBBRR: + *spr_val = vcpu->arch.ebbrr; + break; + case SPRN_BESCR: + *spr_val = vcpu->arch.bescr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c index 51d469f8c9fd..828056ec208f 100644 --- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -900,6 +900,23 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu, case BOOK3S_INTERRUPT_PERFMON: r = RESUME_GUEST; break; + case BOOK3S_INTERRUPT_FAC_UNAVAIL: + { + /* + * Check for the facility that need to be emulated + */ + ulong fscr_ic = vcpu->arch.shadow_fscr >> 56; + if (fscr_ic != FSCR_EBB_LG) { + /* + * We only disable EBB facility. + * So only emulate that.I don't understand the comment. We emulate nothing at all here. We either - hit an EBB unavailable in which case we send the guest an illegal instruction interrupt or we - hit another facility interrupt in which case we forward the interrupt to the guest, but not the interrupt cause (fscr_ic).
What i wanted to achive was, enable both TAR and DSCR and disable EBB. The reason to disable EBB was, we are still not clear how to handle PMU details in PR. Now with FSCR carrying that value, we would get facility unavailable interrupt when we try to mfspr/mtspr few EBB related registers. The PR guest kernel do that on context switch (_switch). Now what we do here is to fallthrough and handle that via emulate mtspr/mfspr. If we get facility unavailable interrupt due to any other reason, that means PR guest has explicitly disabled that facility. Hence we forward that as facility unavailable interrupt to guest allowing PR guest to handle that.
I think the EBB case should be explicit:
/* We don't allow EBB inside the guest, so something must have gone
terribly wrong */
if (fscr_ic == FSCR_EBB_LG)
BUG();Instead of BUG, we do handle few mfspr/mtspr via emulate which we are mostly ignoring. For event based branch instruction, the emulation will fail and we will send 0x700(interrupt program) to PR guest right ?
vcpu->arch.fscr &= ~FSCR_IC_MASK; vcpu->arch.fscr |= vcpu->arch.shadow_fscr & FSCR_IC_MASK; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); r = RESUME_GUEST; break;
-aneesh
From: Alexander Graf <hidden>
Date: 2014-01-31 12:02:19
On 31.01.2014, at 12:40, Aneesh Kumar K.V = [off-list ref] wrote:
Alexander Graf [off-list ref] writes: =20quoted
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
At this point we allow all the supported facilities except EBB. So forward the interrupt to guest as illegal instruction. =20 Signed-off-by: Aneesh Kumar K.V <redacted> --- arch/powerpc/include/asm/kvm_asm.h | 4 +++- arch/powerpc/kvm/book3s.c | 4 ++++ arch/powerpc/kvm/book3s_emulate.c | 18 ++++++++++++++++++ arch/powerpc/kvm/book3s_pr.c | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) =20diff --git a/arch/powerpc/include/asm/kvm_asm.h =
b/arch/powerpc/include/asm/kvm_asm.h
quoted
quoted
index 1bd92fd43cfb..799244face51 100644--- a/arch/powerpc/include/asm/kvm_asm.h +++ b/arch/powerpc/include/asm/kvm_asm.h@@ -99,6 +99,7 @@ #define BOOK3S_INTERRUPT_PERFMON 0xf00 #define BOOK3S_INTERRUPT_ALTIVEC 0xf20 #define BOOK3S_INTERRUPT_VSX 0xf40 +#define BOOK3S_INTERRUPT_FAC_UNAVAIL 0xf60=20 #define BOOK3S_IRQPRIO_SYSTEM_RESET 0 #define BOOK3S_IRQPRIO_DATA_SEGMENT 1@@ -117,7 +118,8 @@ #define BOOK3S_IRQPRIO_DECREMENTER 14 #define BOOK3S_IRQPRIO_PERFORMANCE_MONITOR 15 #define BOOK3S_IRQPRIO_EXTERNAL_LEVEL 16 -#define BOOK3S_IRQPRIO_MAX 17 +#define BOOK3S_IRQPRIO_FAC_UNAVAIL 17 +#define BOOK3S_IRQPRIO_MAX 18=20 #define BOOK3S_HFLAG_DCBZ32 0x1 #define BOOK3S_HFLAG_SLB 0x2diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 8912608b7e1b..a9aea28c2677 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c@@ -143,6 +143,7 @@ static int kvmppc_book3s_vec2irqprio(unsigned =
int vec)
quoted
quoted
case 0xd00: prio =3D BOOK3S_IRQPRIO_DEBUG; break; case 0xf20: prio =3D BOOK3S_IRQPRIO_ALTIVEC; break; case 0xf40: prio =3D BOOK3S_IRQPRIO_VSX; =
break;
quoted
quoted
+ case 0xf60: prio =3D BOOK3S_IRQPRIO_FAC_UNAVAIL; =
break;
quoted
quoted
default: prio =3D BOOK3S_IRQPRIO_MAX; =
break;
quoted
quoted
} =20@@ -273,6 +274,9 @@ int kvmppc_book3s_irqprio_deliver(struct =
kvm_vcpu *vcpu, unsigned int priority)
quoted
quoted
case BOOK3S_IRQPRIO_PERFORMANCE_MONITOR: vec =3D BOOK3S_INTERRUPT_PERFMON; break; + case BOOK3S_IRQPRIO_FAC_UNAVAIL: + vec =3D BOOK3S_INTERRUPT_FAC_UNAVAIL; + break; default: deliver =3D 0; printk(KERN_ERR "KVM: Unknown interrupt: 0x%x\n", =
priority);
quoted
quoted
diff --git a/arch/powerpc/kvm/book3s_emulate.c =
b/arch/powerpc/kvm/book3s_emulate.c
quoted
quoted
index 60d0b6b745e7..bf6b11021250 100644--- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c@@ -481,6 +481,15 @@ int kvmppc_core_emulate_mtspr_pr(struct =
kvm_vcpu *vcpu, int sprn, ulong spr_val)
quoted
quoted
vcpu->arch.shadow_fscr =3D vcpu->arch.fscr & host_fscr; break; } + case SPRN_EBBHR: + vcpu->arch.ebbhr =3D spr_val; + break; + case SPRN_EBBRR: + vcpu->arch.ebbrr =3D spr_val; + break; + case SPRN_BESCR: + vcpu->arch.bescr =3D spr_val; + break; unprivileged: default: printk(KERN_INFO "KVM: invalid SPR write: %d\n", sprn);@@ -607,6 +616,15 @@ int kvmppc_core_emulate_mfspr_pr(struct =
kvm_vcpu *vcpu, int sprn, ulong *spr_val
quoted
quoted
case SPRN_FSCR: *spr_val =3D vcpu->arch.fscr; break; + case SPRN_EBBHR: + *spr_val =3D vcpu->arch.ebbhr; + break; + case SPRN_EBBRR: + *spr_val =3D vcpu->arch.ebbrr; + break; + case SPRN_BESCR: + *spr_val =3D vcpu->arch.bescr; + break; default: unprivileged: printk(KERN_INFO "KVM: invalid SPR read: %d\n", sprn);diff --git a/arch/powerpc/kvm/book3s_pr.c =
b/arch/powerpc/kvm/book3s_pr.c
quoted
quoted
index 51d469f8c9fd..828056ec208f 100644--- a/arch/powerpc/kvm/book3s_pr.c +++ b/arch/powerpc/kvm/book3s_pr.c@@ -900,6 +900,23 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, =
struct kvm_vcpu *vcpu,
quoted
quoted
case BOOK3S_INTERRUPT_PERFMON: r =3D RESUME_GUEST; break; + case BOOK3S_INTERRUPT_FAC_UNAVAIL: + { + /* + * Check for the facility that need to be emulated + */ + ulong fscr_ic =3D vcpu->arch.shadow_fscr >> 56; + if (fscr_ic !=3D FSCR_EBB_LG) { + /* + * We only disable EBB facility. + * So only emulate that.=20 I don't understand the comment. We emulate nothing at all here. We =
either
quoted
- hit an EBB unavailable in which case we send the guest an =
illegal=20
quoted
instruction interrupt or we - hit another facility interrupt in which case we forward the=20 interrupt to the guest, but not the interrupt cause (fscr_ic). =20=20 What i wanted to achive was, enable both TAR and DSCR and disable EBB. The reason to disable EBB was, we are still not clear how to =
handle
PMU details in PR. Now with FSCR carrying that value, we would get facility unavailable interrupt when we try to mfspr/mtspr few EBB related registers. The PR guest kernel do that on context switch (_switch). Now what we do here is to fallthrough and handle that via emulate mtspr/mfspr. =20 If we get facility unavailable interrupt due to any other reason, that means PR guest has explicitly disabled that facility. Hence we forward that as facility unavailable interrupt to guest allowing PR guest to handle that.=20
Please adjust the comment accordingly. =46rom the code flow that is very =
unclear. "Disable" means we don't allow the guest to access EBB. You do =
want to allow the guest to use a fake version of EBB by emulating the =
facility unavailable interrupt.
if (fscr_ic =3D=3D FSCR_EBB_LG) {
/*
* We filtered EBB out of FSCR so that we get traps whenever the guest =
is trying to
* access EBB registers. Thanks to that we can now emulate these =
instructions and
* expose a virtual (no-op) ebb facility to the guest
*/
<call instruction emulation>
} else {
/* forward interrupt to the guest */
}
Alex
=20 =20quoted
I think the EBB case should be explicit: =20 /* We don't allow EBB inside the guest, so something must have gone=20=
quoted
terribly wrong */ if (fscr_ic =3D=3D FSCR_EBB_LG) BUG(); =20=20 Instead of BUG, we do handle few mfspr/mtspr via emulate which we are mostly ignoring. For event based branch instruction, the emulation =
will
fail and we will send 0x700(interrupt program) to PR guest right ? =20 =20quoted
vcpu->arch.fscr &=3D ~FSCR_IC_MASK; vcpu->arch.fscr |=3D vcpu->arch.shadow_fscr & FSCR_IC_MASK; kvmppc_book3s_queue_irqprio(vcpu, exit_nr); r =3D RESUME_GUEST; break; =20=20 -aneesh =20 -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Paul Mackerras <hidden>
Date: 2014-01-31 22:17:43
On Fri, Jan 31, 2014 at 11:47:44AM +0100, Alexander Graf wrote:
On 31.01.2014, at 11:38, Aneesh Kumar K.V [off-list ref] wrote:quoted
Alexander Graf [off-list ref] writes:quoted
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
We definitely don't need to emulate mtspr, because both the registers are hypervisor resource.This patch description doesn't cover what the patch actually does. It changes the implementation from "always tell the guest it uses 100%" to "give the guest an accurate amount of cpu time spent inside guest context".Will fix thatquoted
Also, I think we either go with full hyp semantics which means we also emulate the offset or we go with no hyp awareness in the guest at all which means we also don't emulate SPURR which is a hyp privileged register.Can you clarify this ?In the 2.06 ISA SPURR is hypervisor privileged. That changed for 2.07 where it became supervisor privileged. So I suppose your patch is ok. When reviewing those patches I only had 2.06 around because power.org was broken.
It's always been supervisor privilege for reading and hypervisor privilege for writing, ever since it was introduced in 2.05, and that hasn't changed. So I think what Aneesh is doing is correct. Regards, Paul.
From: Alexander Graf <hidden>
Date: 2014-02-05 09:15:58
On 31.01.2014, at 23:17, Paul Mackerras [off-list ref] wrote:
On Fri, Jan 31, 2014 at 11:47:44AM +0100, Alexander Graf wrote:quoted
=20 On 31.01.2014, at 11:38, Aneesh Kumar K.V =
[off-list ref] wrote:
quoted
=20quoted
Alexander Graf [off-list ref] writes: =20quoted
On 01/28/2014 05:44 PM, Aneesh Kumar K.V wrote:quoted
We definitely don't need to emulate mtspr, because both the =
registers
quoted
quoted
quoted
quoted
are hypervisor resource.=20 This patch description doesn't cover what the patch actually does. =
It=20
quoted
quoted
quoted
changes the implementation from "always tell the guest it uses =
100%" to=20
quoted
quoted
quoted
"give the guest an accurate amount of cpu time spent inside guest context".=20 Will fix that =20quoted
=20 Also, I think we either go with full hyp semantics which means we =
also=20
quoted
quoted
quoted
emulate the offset or we go with no hyp awareness in the guest at =
all=20
quoted
quoted
quoted
which means we also don't emulate SPURR which is a hyp privileged register.=20 Can you clarify this ?=20 In the 2.06 ISA SPURR is hypervisor privileged. That changed for 2.07 =
where it became supervisor privileged. So I suppose your patch is ok. = When reviewing those patches I only had 2.06 around because power.org = was broken.
=20 It's always been supervisor privilege for reading and hypervisor privilege for writing, ever since it was introduced in 2.05, and that hasn't changed. So I think what Aneesh is doing is correct.
This is what ISA 2.06B says: 308 SPURR hypv hypv 64 S 309 PURR hypv yes 64 S And this is ISA 2.07: 308 SPURR hypv yes 64 S 309 PURR hypv yes 64 S So as you can see, from 2.06 to 2.07 SPURR became supervisor readable. = Either the spec is wrong, the respective POWER CPUs don't implement the = spec correctly or "hypv" doesn't mean "hypv" but means "may be hypv or = yes". I think in the context of this patch it's perfectly reasonable to treat = SPURR as supervisor readable. Alex