Message ID | 20240130204533.693853-22-maz@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM/arm64: VM configuration enforcement | expand |
On Tue, Jan 30, 2024 at 08:45:28PM +0000, Marc Zyngier wrote: > Outer Shareable and Range TLBI instructions shouldn't be made available > to the guest if they are not advertised. Use FGU to disable those, > and set HCR_EL2.TLBIOS in the case the host doesn't have FGT. Note > that in that later case, we cannot efficiently disable TLBI Range > instructions, as this would require to trap all TLBIs. > > Signed-off-by: Marc Zyngier <maz@kernel.org> > --- > arch/arm64/kvm/sys_regs.c | 34 ++++++++++++++++++++++++++++++++++ > 1 file changed, 34 insertions(+) > > diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c > index 39e7c7f74717..f07ee7c89822 100644 > --- a/arch/arm64/kvm/sys_regs.c > +++ b/arch/arm64/kvm/sys_regs.c > @@ -3948,6 +3948,14 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu) > > mutex_lock(&kvm->arch.config_lock); > > + /* > + * In the absence of FGT, we cannot independently trap TLBI > + * Range instructions. This isn't great, but trapping all > + * TLBIs would be far worse. Live with it... > + */ > + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS)) > + vcpu->arch.hcr_el2 |= HCR_TTLBOS; > + > if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags)) > goto out; > > @@ -3960,6 +3968,32 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu) > HFGxTR_EL2_nSMPRI_EL1_MASK | > HFGxTR_EL2_nTPIDR2_EL0_MASK); > > + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS)) > + kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS| > + HFGITR_EL2_TLBIRVALE1OS | > + HFGITR_EL2_TLBIRVAAE1OS | > + HFGITR_EL2_TLBIRVAE1OS | > + HFGITR_EL2_TLBIVAALE1OS | > + HFGITR_EL2_TLBIVALE1OS | > + HFGITR_EL2_TLBIVAAE1OS | > + HFGITR_EL2_TLBIASIDE1OS | > + HFGITR_EL2_TLBIVAE1OS | > + HFGITR_EL2_TLBIVMALLE1OS); > + > + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE)) > + kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1 | > + HFGITR_EL2_TLBIRVALE1 | > + HFGITR_EL2_TLBIRVAAE1 | > + HFGITR_EL2_TLBIRVAE1 | > + HFGITR_EL2_TLBIRVAALE1IS| > + HFGITR_EL2_TLBIRVALE1IS | > + HFGITR_EL2_TLBIRVAAE1IS | > + HFGITR_EL2_TLBIRVAE1IS | > + HFGITR_EL2_TLBIRVAALE1OS| > + HFGITR_EL2_TLBIRVALE1OS | > + HFGITR_EL2_TLBIRVAAE1OS | > + HFGITR_EL2_TLBIRVAE1OS); > + > set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags); > out: > mutex_unlock(&kvm->arch.config_lock); Commit message update *and* a comment, generous! Reviewed-by: Joey Gouly <joey.gouly@arm.com> Thanks, Joey
diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 39e7c7f74717..f07ee7c89822 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -3948,6 +3948,14 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu) mutex_lock(&kvm->arch.config_lock); + /* + * In the absence of FGT, we cannot independently trap TLBI + * Range instructions. This isn't great, but trapping all + * TLBIs would be far worse. Live with it... + */ + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS)) + vcpu->arch.hcr_el2 |= HCR_TTLBOS; + if (test_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags)) goto out; @@ -3960,6 +3968,32 @@ void kvm_init_sysreg(struct kvm_vcpu *vcpu) HFGxTR_EL2_nSMPRI_EL1_MASK | HFGxTR_EL2_nTPIDR2_EL0_MASK); + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, OS)) + kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1OS| + HFGITR_EL2_TLBIRVALE1OS | + HFGITR_EL2_TLBIRVAAE1OS | + HFGITR_EL2_TLBIRVAE1OS | + HFGITR_EL2_TLBIVAALE1OS | + HFGITR_EL2_TLBIVALE1OS | + HFGITR_EL2_TLBIVAAE1OS | + HFGITR_EL2_TLBIASIDE1OS | + HFGITR_EL2_TLBIVAE1OS | + HFGITR_EL2_TLBIVMALLE1OS); + + if (!kvm_has_feat(kvm, ID_AA64ISAR0_EL1, TLB, RANGE)) + kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_TLBIRVAALE1 | + HFGITR_EL2_TLBIRVALE1 | + HFGITR_EL2_TLBIRVAAE1 | + HFGITR_EL2_TLBIRVAE1 | + HFGITR_EL2_TLBIRVAALE1IS| + HFGITR_EL2_TLBIRVALE1IS | + HFGITR_EL2_TLBIRVAAE1IS | + HFGITR_EL2_TLBIRVAE1IS | + HFGITR_EL2_TLBIRVAALE1OS| + HFGITR_EL2_TLBIRVALE1OS | + HFGITR_EL2_TLBIRVAAE1OS | + HFGITR_EL2_TLBIRVAE1OS); + set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags); out: mutex_unlock(&kvm->arch.config_lock);
Outer Shareable and Range TLBI instructions shouldn't be made available to the guest if they are not advertised. Use FGU to disable those, and set HCR_EL2.TLBIOS in the case the host doesn't have FGT. Note that in that later case, we cannot efficiently disable TLBI Range instructions, as this would require to trap all TLBIs. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/kvm/sys_regs.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)