Message ID | 1531905547-25478-6-git-send-email-suzuki.poulose@arm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Jul 18, 2018 at 10:18:48AM +0100, Suzuki K Poulose wrote: > We load the stage2 context of a guest for different operations, > including running the guest and tlb maintenance on behalf of the > guest. As of now only the vttbr is private to the guest, but this > is about to change with IPA per VM. Add a helper to load the stage2 > configuration for a VM, which could do the right thing with the > future changes. > > Cc: Christoffer Dall <cdall@kernel.org> > Cc: Marc Zyngier <marc.zyngier@arm.com> > Reviewed-by: Eric Auger <eric.auger@redhat.com> > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> > --- > Changes since v2: > - New patch > --- > arch/arm64/include/asm/kvm_hyp.h | 6 ++++++ > arch/arm64/kvm/hyp/switch.c | 2 +- > arch/arm64/kvm/hyp/tlb.c | 4 ++-- > 3 files changed, 9 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h > index 384c343..82f9994 100644 > --- a/arch/arm64/include/asm/kvm_hyp.h > +++ b/arch/arm64/include/asm/kvm_hyp.h > @@ -155,5 +155,11 @@ void deactivate_traps_vhe_put(void); > u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); > void __noreturn __hyp_do_panic(unsigned long, ...); > > +/* Must be called from hyp code running at EL2 */ more importantly than having to run this at EL2, is that it must have gone through the proper sequence of update_vttbr() and disabling interrupts to avoid using a stale VMID. > +static __always_inline void __hyp_text __load_guest_stage2(struct kvm *kvm) > +{ > + write_sysreg(kvm->arch.vttbr, vttbr_el2); > +} > + > #endif /* __ARM64_KVM_HYP_H__ */ > > diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c > index d496ef5..355fb25 100644 > --- a/arch/arm64/kvm/hyp/switch.c > +++ b/arch/arm64/kvm/hyp/switch.c > @@ -195,7 +195,7 @@ void deactivate_traps_vhe_put(void) > > static void __hyp_text __activate_vm(struct kvm *kvm) > { > - write_sysreg(kvm->arch.vttbr, vttbr_el2); > + __load_guest_stage2(kvm); > } > > static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu) > diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c > index 131c777..4dbd9c6 100644 > --- a/arch/arm64/kvm/hyp/tlb.c > +++ b/arch/arm64/kvm/hyp/tlb.c > @@ -30,7 +30,7 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) > * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so > * let's flip TGE before executing the TLB operation. > */ > - write_sysreg(kvm->arch.vttbr, vttbr_el2); > + __load_guest_stage2(kvm); > val = read_sysreg(hcr_el2); > val &= ~HCR_TGE; > write_sysreg(val, hcr_el2); > @@ -39,7 +39,7 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) > > static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm) > { > - write_sysreg(kvm->arch.vttbr, vttbr_el2); > + __load_guest_stage2(kvm); > isb(); > } > > -- > 2.7.4 > Thanks, -Christoffer
On 30/08/18 10:39, Christoffer Dall wrote: > On Wed, Jul 18, 2018 at 10:18:48AM +0100, Suzuki K Poulose wrote: >> We load the stage2 context of a guest for different operations, >> including running the guest and tlb maintenance on behalf of the >> guest. As of now only the vttbr is private to the guest, but this >> is about to change with IPA per VM. Add a helper to load the stage2 >> configuration for a VM, which could do the right thing with the >> future changes. >> >> Cc: Christoffer Dall <cdall@kernel.org> >> Cc: Marc Zyngier <marc.zyngier@arm.com> >> Reviewed-by: Eric Auger <eric.auger@redhat.com> >> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> >> --- >> Changes since v2: >> - New patch >> --- >> arch/arm64/include/asm/kvm_hyp.h | 6 ++++++ >> arch/arm64/kvm/hyp/switch.c | 2 +- >> arch/arm64/kvm/hyp/tlb.c | 4 ++-- >> 3 files changed, 9 insertions(+), 3 deletions(-) >> >> diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h >> index 384c343..82f9994 100644 >> --- a/arch/arm64/include/asm/kvm_hyp.h >> +++ b/arch/arm64/include/asm/kvm_hyp.h >> @@ -155,5 +155,11 @@ void deactivate_traps_vhe_put(void); >> u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); >> void __noreturn __hyp_do_panic(unsigned long, ...); >> >> +/* Must be called from hyp code running at EL2 */ > > more importantly than having to run this at EL2, is that it must have > gone through the proper sequence of update_vttbr() and disabling > interrupts to avoid using a stale VMID. Right, I will update the comment. Cheers Suzuki
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 384c343..82f9994 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -155,5 +155,11 @@ void deactivate_traps_vhe_put(void); u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); void __noreturn __hyp_do_panic(unsigned long, ...); +/* Must be called from hyp code running at EL2 */ +static __always_inline void __hyp_text __load_guest_stage2(struct kvm *kvm) +{ + write_sysreg(kvm->arch.vttbr, vttbr_el2); +} + #endif /* __ARM64_KVM_HYP_H__ */ diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index d496ef5..355fb25 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -195,7 +195,7 @@ void deactivate_traps_vhe_put(void) static void __hyp_text __activate_vm(struct kvm *kvm) { - write_sysreg(kvm->arch.vttbr, vttbr_el2); + __load_guest_stage2(kvm); } static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu) diff --git a/arch/arm64/kvm/hyp/tlb.c b/arch/arm64/kvm/hyp/tlb.c index 131c777..4dbd9c6 100644 --- a/arch/arm64/kvm/hyp/tlb.c +++ b/arch/arm64/kvm/hyp/tlb.c @@ -30,7 +30,7 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) * bits. Changing E2H is impossible (goodbye TTBR1_EL2), so * let's flip TGE before executing the TLB operation. */ - write_sysreg(kvm->arch.vttbr, vttbr_el2); + __load_guest_stage2(kvm); val = read_sysreg(hcr_el2); val &= ~HCR_TGE; write_sysreg(val, hcr_el2); @@ -39,7 +39,7 @@ static void __hyp_text __tlb_switch_to_guest_vhe(struct kvm *kvm) static void __hyp_text __tlb_switch_to_guest_nvhe(struct kvm *kvm) { - write_sysreg(kvm->arch.vttbr, vttbr_el2); + __load_guest_stage2(kvm); isb(); }