Skip to content

Commit a7f1fa5

Browse files
mrutland-armMarc Zyngier
authored andcommitted
KVM: arm64: Explicitly handle BRBE traps as UNDEFINED
The Branch Record Buffer Extension (BRBE) adds a number of system registers and instructions which we don't currently intend to expose to guests. Our existing logic handles this safely, but this could be improved with some explicit handling of BRBE. KVM currently hides BRBE from guests: the cpufeature code's ftr_id_aa64dfr0[] table doesn't have an entry for the BRBE field, and so this will be zero in the sanitised value of ID_AA64DFR0 exposed to guests via read_sanitised_id_aa64dfr0_el1(). KVM currently traps BRBE usage from guests: the default configuration of the fine-grained trap controls HDFGRTR_EL2.{nBRBDATA,nBRBCTL,nBRBIDR} and HFGITR_EL2.{nBRBINJ_nBRBIALL} cause these to be trapped to EL2. Well-behaved guests shouldn't try to use the registers or instructions, but badly-behaved guests could use these, resulting in unnecessary warnings from KVM before it injects an UNDEF, e.g. | kvm [197]: Unsupported guest access at: 401c98 | { Op0( 2), Op1( 1), CRn( 9), CRm( 0), Op2( 0), func_read }, | kvm [197]: Unsupported guest access at: 401d04 | { Op0( 2), Op1( 1), CRn( 9), CRm( 0), Op2( 1), func_read }, | kvm [197]: Unsupported guest access at: 401d70 | { Op0( 2), Op1( 1), CRn( 9), CRm( 2), Op2( 0), func_read }, | kvm [197]: Unsupported guest access at: 401ddc | { Op0( 2), Op1( 1), CRn( 9), CRm( 1), Op2( 0), func_read }, | kvm [197]: Unsupported guest access at: 401e48 | { Op0( 2), Op1( 1), CRn( 9), CRm( 1), Op2( 1), func_read }, | kvm [197]: Unsupported guest access at: 401eb4 | { Op0( 2), Op1( 1), CRn( 9), CRm( 1), Op2( 2), func_read }, | kvm [197]: Unsupported guest access at: 401f20 | { Op0( 2), Op1( 1), CRn( 9), CRm( 0), Op2( 2), func_read }, | kvm [197]: Unsupported guest access at: 401f8c | { Op0( 1), Op1( 1), CRn( 7), CRm( 2), Op2( 4), func_write }, | kvm [197]: Unsupported guest access at: 401ff8 | { Op0( 1), Op1( 1), CRn( 7), CRm( 2), Op2( 5), func_write }, As with other features that we know how to handle, these warnings aren't particularly interesting, and we can simply treat these as UNDEFINED without any warning. Add the necessary fine-grained undef configuration to make this happen, as suggested by Marc Zyngier: https://lore.kernel.org/linux-arm-kernel/[email protected]/ At the same time, update read_sanitised_id_aa64dfr0_el1() to hide BRBE from guests, as we do for SPE. This will prevent accidentally exposing BRBE to guests if/when ftr_id_aa64dfr0[] gains a BRBE entry. Cc: Anshuman Khandual <[email protected]> Signed-off-by: Mark Rutland <[email protected]> Signed-off-by: Rob Herring (Arm) <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent dea8838 commit a7f1fa5

File tree

1 file changed

+11
-0
lines changed

1 file changed

+11
-0
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1806,6 +1806,9 @@ static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
18061806
/* Hide SPE from guests */
18071807
val &= ~ID_AA64DFR0_EL1_PMSVer_MASK;
18081808

1809+
/* Hide BRBE from guests */
1810+
val &= ~ID_AA64DFR0_EL1_BRBE_MASK;
1811+
18091812
return val;
18101813
}
18111814

@@ -4973,6 +4976,14 @@ void kvm_calculate_traps(struct kvm_vcpu *vcpu)
49734976
kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
49744977
HAFGRTR_EL2_RES1);
49754978

4979+
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, BRBE, IMP)) {
4980+
kvm->arch.fgu[HDFGRTR_GROUP] |= (HDFGRTR_EL2_nBRBDATA |
4981+
HDFGRTR_EL2_nBRBCTL |
4982+
HDFGRTR_EL2_nBRBIDR);
4983+
kvm->arch.fgu[HFGITR_GROUP] |= (HFGITR_EL2_nBRBINJ |
4984+
HFGITR_EL2_nBRBIALL);
4985+
}
4986+
49764987
set_bit(KVM_ARCH_FLAG_FGU_INITIALIZED, &kvm->arch.flags);
49774988
out:
49784989
mutex_unlock(&kvm->arch.config_lock);

0 commit comments

Comments
 (0)