[PATCH v16 38/45] KVM: arm64: CCA: Propagate breakpoint and watchpoint counts to userspace
Steven Price <[email protected]> Mon, 3 Aug 2026 14:43:54 +0100
| Newsgroups | dev.linux.lists.linux-coco,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Jean-Philippe Brucker <[email protected]> The RMM describes the maximum number of BPs/WPs available to the guest in the Feature Register 0. Propagate those numbers into ID_AA64DFR0_EL1, which is visible to userspace. A VMM needs this information in order to set up realm parameters. Signed-off-by: Jean-Philippe Brucker <[email protected]> Signed-off-by: Steven Price <[email protected]> Reviewed-by: Gavin Shan <[email protected]> Reviewed-by: Suzuki K Poulose <[email protected]> Reviewed-by: Joey Gouly <[email protected]> --- arch/arm64/include/asm/kvm_rmi.h | 2 ++ arch/arm64/kvm/rmi.c | 19 +++++++++++++++++++ arch/arm64/kvm/sys_regs.c | 3 +++ 3 files changed, 24 insertions(+) diff --git a/arch/arm64/include/asm/kvm_rmi.h b/arch/arm64/include/asm/kvm_rmi.h index 13933f0e555d..7d27c17276bf 100644 --- a/arch/arm64/include/asm/kvm_rmi.h +++ b/arch/arm64/include/asm/kvm_rmi.h @@ -98,6 +98,8 @@ struct realm_rec { void kvm_init_rmi(void); u32 kvm_rmm_ipa_limit(void); +u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val); + bool kvm_rmi_supports_sve(void); int kvm_init_realm(struct kvm *kvm); diff --git a/arch/arm64/kvm/rmi.c b/arch/arm64/kvm/rmi.c index 0d46768022df..de893308148e 100644 --- a/arch/arm64/kvm/rmi.c +++ b/arch/arm64/kvm/rmi.c @@ -36,6 +36,25 @@ u32 kvm_rmm_ipa_limit(void) return u64_get_bits(rmi_feat_reg(0), RMI_FEATURE_REGISTER_0_S2SZ); } +u64 kvm_realm_reset_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val) +{ + u32 bps = u64_get_bits(rmi_feat_reg(0), RMI_FEATURE_REGISTER_0_NUM_BPS); + u32 wps = u64_get_bits(rmi_feat_reg(0), RMI_FEATURE_REGISTER_0_NUM_WPS); + u32 ctx_cmps; + + /* Ensure CTX_CMPs is still valid */ + ctx_cmps = FIELD_GET(ID_AA64DFR0_EL1_CTX_CMPs, val); + ctx_cmps = min(bps, ctx_cmps); + + val &= ~(ID_AA64DFR0_EL1_BRPs_MASK | ID_AA64DFR0_EL1_WRPs_MASK | + ID_AA64DFR0_EL1_CTX_CMPs); + val |= FIELD_PREP(ID_AA64DFR0_EL1_BRPs_MASK, bps) | + FIELD_PREP(ID_AA64DFR0_EL1_WRPs_MASK, wps) | + FIELD_PREP(ID_AA64DFR0_EL1_CTX_CMPs, ctx_cmps); + + return val; +} + static int get_start_level(struct realm *realm) { return 4 - stage2_pgtable_levels(realm->ia_bits); diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 5d5c579d4579..e0fe9f2562bc 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -2142,6 +2142,9 @@ static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val) /* Hide BRBE from guests */ val &= ~ID_AA64DFR0_EL1_BRBE_MASK; + if (vcpu_is_rec(vcpu)) + return kvm_realm_reset_id_aa64dfr0_el1(vcpu, val); + return val; } -- 2.43.0