Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
Alexander Graf writes: > --- a/arch/powerpc/include/asm/reg.h > +++ b/arch/powerpc/include/asm/reg.h > @@ -25,7 +25,6 @@ > #ifdef CONFIG_8xx > #include > #endif /* CONFIG_8xx */ > -#include > > #define MSR_SF_LG 63 /* Enable 64 bit mode */ > #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on > 630 */ > @@ -1210,12 +1209,6 @@ static inline unsigned long mfvtb (void) > if (cpu_has_feature(CPU_FTR_ARCH_207S)) > return mfspr(SPRN_VTB); > #endif > - /* > -* The above mfspr will be a no-op on anything before Power8 > -* That can result in random values returned. We need to > -* capture that. > -*/ > - BUG(); > return 0; > } (i missed CCing aneesh on this mail in reply to the build robot, so inserting the same reply here) the only place that calls it also does the cpu_has_feature() check and returns 0 ifndef CONFIG_PPC_BOOK3S_64 or !cpu_has_feature(). Looking get_vtb (the only caller) and the places it's called (as well as PowerISA 2.07) I think in the emulation code we're missing invoking the "system privileged instruction error handler" as the VTB SPR has spr bit 0 set to 1 (page 107 of PowerISA 2.07, mfspr docs). That being said... any guest sholud do the cpu_has_feature check themselves, so this probably isn't an issue in the real world. Certainly the host really shouldn't BUG() for what is really a guest issue (actually.. this would be a good DoS attack on < Power8 host). Reviewed-by: Stewart Smith ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 06.06.14 18:27, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 For some reason BUG() doesn't always trigger the "execution stops here" logic in gcc. So I've squashed this patch into yours. Alex diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 3e7085d..99de6ad 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1206,6 +1206,7 @@ static inline unsigned long mfvtb (void) * capture that. */ BUG(); +return 0; } #ifdef __powerpc64__ you can then drop the include header change. ie, #include Yeah, things are even worse than I thought. I've eventually squashed the following in. a NOP'ed mfspr() won't keep the branch from blr'ing, so we'd never hit the BUG() anyway. Alex diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1f34ef7..c8f3381 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -25,7 +25,6 @@ #ifdef CONFIG_8xx #include #endif /* CONFIG_8xx */ -#include #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -1210,12 +1209,6 @@ static inline unsigned long mfvtb (void) if (cpu_has_feature(CPU_FTR_ARCH_207S)) return mfspr(SPRN_VTB); #endif - /* -* The above mfspr will be a no-op on anything before Power8 -* That can result in random values returned. We need to -* capture that. -*/ - BUG(); return 0; } ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
Alexander Graf writes: > On 05.06.14 14:08, Aneesh Kumar K.V wrote: >> virtual time base register is a per VM, per cpu register that needs >> to be 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 > > For some reason BUG() doesn't always trigger the "execution stops here" > logic in gcc. So I've squashed this patch into yours. > > > Alex > > > diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h > index 3e7085d..99de6ad 100644 > --- a/arch/powerpc/include/asm/reg.h > +++ b/arch/powerpc/include/asm/reg.h > @@ -1206,6 +1206,7 @@ static inline unsigned long mfvtb (void) >* capture that. >*/ > BUG(); > +return 0; > } > > #ifdef __powerpc64__ you can then drop the include header change. ie, #include -aneesh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 For some reason BUG() doesn't always trigger the "execution stops here" logic in gcc. So I've squashed this patch into yours. Alex diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 3e7085d..99de6ad 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -1206,6 +1206,7 @@ static inline unsigned long mfvtb (void) * capture that. */ BUG(); +return 0; } #ifdef __powerpc64__ ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 06.06.14 00:32, Alexander Graf wrote: On 05.06.14 19:33, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 17:50, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 ... break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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; Doesn't this mean that vtb can be the same 2 when the guest reads it 2 times in a row without getting preempted? But a mfspr will result in VM exit and that would make sure we update vcpu->arch.vtb with the correct value. We only call kvmppc_core_vcpu_put_pr() when we context switch away from KVM, so it won't be updated, no? kvmppc_copy_from_svcpu is also called from VM exit path (book3s_interrupt.S) ... where it will run into this code path: /* * Maybe we were already preempted and synced the svcpu from * our preempt notifiers. Don't bother touching this svcpu then. */ if (!svcpu->in_use) goto out; Scratch that. We're always calling this on entry/exit, so you're right. Alex ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 05.06.14 19:33, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 17:50, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 ... break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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; Doesn't this mean that vtb can be the same 2 when the guest reads it 2 times in a row without getting preempted? But a mfspr will result in VM exit and that would make sure we update vcpu->arch.vtb with the correct value. We only call kvmppc_core_vcpu_put_pr() when we context switch away from KVM, so it won't be updated, no? kvmppc_copy_from_svcpu is also called from VM exit path (book3s_interrupt.S) ... where it will run into this code path: /* * Maybe we were already preempted and synced the svcpu from * our preempt notifiers. Don't bother touching this svcpu then. */ if (!svcpu->in_use) goto out; Alex ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
Alexander Graf writes: > On 05.06.14 17:50, Aneesh Kumar K.V wrote: >> Alexander Graf writes: >> >>> On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 ... break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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; >>> Doesn't this mean that vtb can be the same 2 when the guest reads it 2 >>> times in a row without getting preempted? >> >> But a mfspr will result in VM exit and that would make sure we >> update vcpu->arch.vtb with the correct value. > > We only call kvmppc_core_vcpu_put_pr() when we context switch away from > KVM, so it won't be updated, no? > > kvmppc_copy_from_svcpu is also called from VM exit path (book3s_interrupt.S) -aneesh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 05.06.14 17:50, Aneesh Kumar K.V wrote: Alexander Graf writes: On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/reg.h | 15 +++ arch/powerpc/include/asm/time.h | 9 + arch/powerpc/kvm/book3s.c | 6 ++ arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_hv.c| 6 -- arch/powerpc/kvm/book3s_pr.c| 3 ++- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 4a58731a0a72..bd3caeaeebe1 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -505,6 +505,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 4852bcf270f3..3e7085d8af90 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -25,6 +25,7 @@ #ifdef CONFIG_8xx #include #endif /* CONFIG_8xx */ +#include #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -1193,6 +1194,20 @@ : "r" ((unsigned long)(v)) \ : "memory") +static inline unsigned long mfvtb (void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfspr(SPRN_VTB); +#endif + /* +* The above mfspr will be a no-op on anything before Power8 +* That can result in random values returned. We need to +* capture that. +*/ + BUG(); +} + #ifdef __powerpc64__ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb() ({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 1d428e6007ca..03cbada59d3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -102,6 +102,15 @@ static inline u64 get_rtc(void) return (u64)hi * 10 + lo; } +static inline u64 get_vtb(void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfvtb(); +#endif + return 0; +} + #ifdef CONFIG_PPC64 static inline u64 get_tb(void) { diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 52c654dbd41a..ae43e4178ecd 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -646,6 +646,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: val = get_reg_val(reg->id, vcpu->arch.bescr); break; + case KVM_REG_PPC_VTB: + val = get_reg_val(reg->id, vcpu->arch.vtb); + break; default: r = -EINVAL; break; @@ -750,6 +753,9 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: vcpu->arch.bescr = set_reg_val(reg->id, val); break; + case KVM_REG_PPC_VTB: + vcpu->arch.vtb = set_reg_val(reg->id, val); + break; default: r = -EINVAL; break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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; Doesn't this mean that vtb can be the same 2 when the guest reads it 2 times in a row without getting preempted? But a mfspr will result in VM exit and that would make sure we update vcpu->arch.vtb with the correct value. We only call kvmppc_core_vcpu_put_pr() when we context switch away from KVM, so it won't be updated, no? Alex ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
Alexander Graf writes: > On 05.06.14 14:08, Aneesh Kumar K.V wrote: >> virtual time base register is a per VM, per cpu register that needs >> to be 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 >> --- >> arch/powerpc/include/asm/kvm_host.h | 1 + >> arch/powerpc/include/asm/reg.h | 15 +++ >> arch/powerpc/include/asm/time.h | 9 + >> arch/powerpc/kvm/book3s.c | 6 ++ >> arch/powerpc/kvm/book3s_emulate.c | 3 +++ >> arch/powerpc/kvm/book3s_hv.c| 6 -- >> arch/powerpc/kvm/book3s_pr.c| 3 ++- >> 7 files changed, 36 insertions(+), 7 deletions(-) >> >> diff --git a/arch/powerpc/include/asm/kvm_host.h >> b/arch/powerpc/include/asm/kvm_host.h >> index 4a58731a0a72..bd3caeaeebe1 100644 >> --- a/arch/powerpc/include/asm/kvm_host.h >> +++ b/arch/powerpc/include/asm/kvm_host.h >> @@ -505,6 +505,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 4852bcf270f3..3e7085d8af90 100644 >> --- a/arch/powerpc/include/asm/reg.h >> +++ b/arch/powerpc/include/asm/reg.h >> @@ -25,6 +25,7 @@ >> #ifdef CONFIG_8xx >> #include >> #endif /* CONFIG_8xx */ >> +#include >> >> #define MSR_SF_LG 63 /* Enable 64 bit mode */ >> #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ >> @@ -1193,6 +1194,20 @@ >> : "r" ((unsigned long)(v)) \ >> : "memory") >> >> +static inline unsigned long mfvtb (void) >> +{ >> +#ifdef CONFIG_PPC_BOOK3S_64 >> +if (cpu_has_feature(CPU_FTR_ARCH_207S)) >> +return mfspr(SPRN_VTB); >> +#endif >> +/* >> + * The above mfspr will be a no-op on anything before Power8 >> + * That can result in random values returned. We need to >> + * capture that. >> + */ >> +BUG(); >> +} >> + >> #ifdef __powerpc64__ >> #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) >> #define mftb() ({unsigned long rval; >> \ >> diff --git a/arch/powerpc/include/asm/time.h >> b/arch/powerpc/include/asm/time.h >> index 1d428e6007ca..03cbada59d3a 100644 >> --- a/arch/powerpc/include/asm/time.h >> +++ b/arch/powerpc/include/asm/time.h >> @@ -102,6 +102,15 @@ static inline u64 get_rtc(void) >> return (u64)hi * 10 + lo; >> } >> >> +static inline u64 get_vtb(void) >> +{ >> +#ifdef CONFIG_PPC_BOOK3S_64 >> +if (cpu_has_feature(CPU_FTR_ARCH_207S)) >> +return mfvtb(); >> +#endif >> +return 0; >> +} >> + >> #ifdef CONFIG_PPC64 >> static inline u64 get_tb(void) >> { >> diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c >> index 52c654dbd41a..ae43e4178ecd 100644 >> --- a/arch/powerpc/kvm/book3s.c >> +++ b/arch/powerpc/kvm/book3s.c >> @@ -646,6 +646,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, >> struct kvm_one_reg *reg) >> case KVM_REG_PPC_BESCR: >> val = get_reg_val(reg->id, vcpu->arch.bescr); >> break; >> +case KVM_REG_PPC_VTB: >> +val = get_reg_val(reg->id, vcpu->arch.vtb); >> +break; >> default: >> r = -EINVAL; >> break; >> @@ -750,6 +753,9 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, >> struct kvm_one_reg *reg) >> case KVM_REG_PPC_BESCR: >> vcpu->arch.bescr = set_reg_val(reg->id, val); >> break; >> +case KVM_REG_PPC_VTB: >> +vcpu->arch.vtb = set_reg_val(reg->id, val); >> +break; >> default: >> r = -EINVAL; >> break; >> diff --git a/arch/powerpc/kvm/book3s_emulate.c >> b/arch/powerpc/kvm/book3s_emulate.c >> index 3565e775b61b..1bb16a59dcbc 100644 >> --- a/arch/powerpc/kvm/book3s_emulate.c >> +++ b/arch/powerpc/kvm/book3s_emulate.c >> @@ -577,6 +577,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; > > Doesn't this mean that vtb can be the same 2 when the guest reads it 2 > times in a row without getting preempted? But a mfspr will result in VM exit and that would make sure we update vcpu->arch.vtb with the correct value. -aneesh ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
On 05.06.14 14:08, Aneesh Kumar K.V wrote: virtual time base register is a per VM, per cpu register that needs to be 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 --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/reg.h | 15 +++ arch/powerpc/include/asm/time.h | 9 + arch/powerpc/kvm/book3s.c | 6 ++ arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_hv.c| 6 -- arch/powerpc/kvm/book3s_pr.c| 3 ++- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 4a58731a0a72..bd3caeaeebe1 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -505,6 +505,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 4852bcf270f3..3e7085d8af90 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -25,6 +25,7 @@ #ifdef CONFIG_8xx #include #endif /* CONFIG_8xx */ +#include #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG61 /* Interrupt 64b mode valid on 630 */ @@ -1193,6 +1194,20 @@ : "r" ((unsigned long)(v)) \ : "memory") +static inline unsigned long mfvtb (void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfspr(SPRN_VTB); +#endif + /* +* The above mfspr will be a no-op on anything before Power8 +* That can result in random values returned. We need to +* capture that. +*/ + BUG(); +} + #ifdef __powerpc64__ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb()({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 1d428e6007ca..03cbada59d3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -102,6 +102,15 @@ static inline u64 get_rtc(void) return (u64)hi * 10 + lo; } +static inline u64 get_vtb(void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfvtb(); +#endif + return 0; +} + #ifdef CONFIG_PPC64 static inline u64 get_tb(void) { diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 52c654dbd41a..ae43e4178ecd 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -646,6 +646,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: val = get_reg_val(reg->id, vcpu->arch.bescr); break; + case KVM_REG_PPC_VTB: + val = get_reg_val(reg->id, vcpu->arch.vtb); + break; default: r = -EINVAL; break; @@ -750,6 +753,9 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: vcpu->arch.bescr = set_reg_val(reg->id, val); break; + case KVM_REG_PPC_VTB: + vcpu->arch.vtb = set_reg_val(reg->id, val); + break; default: r = -EINVAL; break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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; Doesn't this mean that vtb can be the same 2 when the guest reads it 2 times in a row without getting preempted? Alex + break; case SPRN_GQR0: case SPRN_GQR1: case SPRN_GQR2: diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index aba05bbb3e74..f6ac58336b3f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -897,9 +897,6 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, case KVM_REG_PPC_IC: *val = get_reg_val(id, vcpu->arch.ic); break; - case KVM_REG_PPC_VTB: - *val
[PATCH 1/4] KVM: PPC: BOOK3S: PR: Emulate virtual timebase register
virtual time base register is a per VM, per cpu register that needs to be 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 --- arch/powerpc/include/asm/kvm_host.h | 1 + arch/powerpc/include/asm/reg.h | 15 +++ arch/powerpc/include/asm/time.h | 9 + arch/powerpc/kvm/book3s.c | 6 ++ arch/powerpc/kvm/book3s_emulate.c | 3 +++ arch/powerpc/kvm/book3s_hv.c| 6 -- arch/powerpc/kvm/book3s_pr.c| 3 ++- 7 files changed, 36 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 4a58731a0a72..bd3caeaeebe1 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -505,6 +505,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 4852bcf270f3..3e7085d8af90 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -25,6 +25,7 @@ #ifdef CONFIG_8xx #include #endif /* CONFIG_8xx */ +#include #define MSR_SF_LG 63 /* Enable 64 bit mode */ #define MSR_ISF_LG 61 /* Interrupt 64b mode valid on 630 */ @@ -1193,6 +1194,20 @@ : "r" ((unsigned long)(v)) \ : "memory") +static inline unsigned long mfvtb (void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfspr(SPRN_VTB); +#endif + /* +* The above mfspr will be a no-op on anything before Power8 +* That can result in random values returned. We need to +* capture that. +*/ + BUG(); +} + #ifdef __powerpc64__ #if defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_FSL_BOOK3E) #define mftb() ({unsigned long rval; \ diff --git a/arch/powerpc/include/asm/time.h b/arch/powerpc/include/asm/time.h index 1d428e6007ca..03cbada59d3a 100644 --- a/arch/powerpc/include/asm/time.h +++ b/arch/powerpc/include/asm/time.h @@ -102,6 +102,15 @@ static inline u64 get_rtc(void) return (u64)hi * 10 + lo; } +static inline u64 get_vtb(void) +{ +#ifdef CONFIG_PPC_BOOK3S_64 + if (cpu_has_feature(CPU_FTR_ARCH_207S)) + return mfvtb(); +#endif + return 0; +} + #ifdef CONFIG_PPC64 static inline u64 get_tb(void) { diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 52c654dbd41a..ae43e4178ecd 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -646,6 +646,9 @@ int kvm_vcpu_ioctl_get_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: val = get_reg_val(reg->id, vcpu->arch.bescr); break; + case KVM_REG_PPC_VTB: + val = get_reg_val(reg->id, vcpu->arch.vtb); + break; default: r = -EINVAL; break; @@ -750,6 +753,9 @@ int kvm_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu, struct kvm_one_reg *reg) case KVM_REG_PPC_BESCR: vcpu->arch.bescr = set_reg_val(reg->id, val); break; + case KVM_REG_PPC_VTB: + vcpu->arch.vtb = set_reg_val(reg->id, val); + break; default: r = -EINVAL; break; diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c index 3565e775b61b..1bb16a59dcbc 100644 --- a/arch/powerpc/kvm/book3s_emulate.c +++ b/arch/powerpc/kvm/book3s_emulate.c @@ -577,6 +577,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_hv.c b/arch/powerpc/kvm/book3s_hv.c index aba05bbb3e74..f6ac58336b3f 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -897,9 +897,6 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id, case KVM_REG_PPC_IC: *val = get_reg_val(id, vcpu->arch.ic); break; - case KVM_REG_PPC_VTB: - *val = get_reg_val(id, vcpu->arch.vtb); - break; case KVM_REG_PPC_CSIGR: *val = get_reg_val(id, vcpu->arch.csigr); break; @@ -1097,9 +1094,6 @@ static