mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-07 13:43:51 +00:00
KVM: arm64: nv: Add trap forwarding for CNTHCTL_EL2
Describe the CNTHCTL_EL2 register, and associate it with all the sysregs it allows to trap. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Jing Zhang <jingzhangos@google.com> Link: https://lore.kernel.org/r/20230815183903.2735724-19-maz@kernel.org
This commit is contained in:
parent
cb31632c44
commit
e880bd3363
@ -100,9 +100,11 @@ enum cgt_group_id {
|
||||
|
||||
/*
|
||||
* Anything after this point requires a callback evaluating a
|
||||
* complex trap condition. Hopefully we'll never need this...
|
||||
* complex trap condition. Ugly stuff.
|
||||
*/
|
||||
__COMPLEX_CONDITIONS__,
|
||||
CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
|
||||
CGT_CNTHCTL_EL1PTEN,
|
||||
|
||||
/* Must be last */
|
||||
__NR_CGT_GROUP_IDS__
|
||||
@ -369,10 +371,51 @@ static const enum cgt_group_id *coarse_control_combo[] = {
|
||||
|
||||
typedef enum trap_behaviour (*complex_condition_check)(struct kvm_vcpu *);
|
||||
|
||||
/*
|
||||
* Warning, maximum confusion ahead.
|
||||
*
|
||||
* When E2H=0, CNTHCTL_EL2[1:0] are defined as EL1PCEN:EL1PCTEN
|
||||
* When E2H=1, CNTHCTL_EL2[11:10] are defined as EL1PTEN:EL1PCTEN
|
||||
*
|
||||
* Note the single letter difference? Yet, the bits have the same
|
||||
* function despite a different layout and a different name.
|
||||
*
|
||||
* We don't try to reconcile this mess. We just use the E2H=0 bits
|
||||
* to generate something that is in the E2H=1 format, and live with
|
||||
* it. You're welcome.
|
||||
*/
|
||||
static u64 get_sanitized_cnthctl(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 val = __vcpu_sys_reg(vcpu, CNTHCTL_EL2);
|
||||
|
||||
if (!vcpu_el2_e2h_is_set(vcpu))
|
||||
val = (val & (CNTHCTL_EL1PCEN | CNTHCTL_EL1PCTEN)) << 10;
|
||||
|
||||
return val & ((CNTHCTL_EL1PCEN | CNTHCTL_EL1PCTEN) << 10);
|
||||
}
|
||||
|
||||
static enum trap_behaviour check_cnthctl_el1pcten(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (get_sanitized_cnthctl(vcpu) & (CNTHCTL_EL1PCTEN << 10))
|
||||
return BEHAVE_HANDLE_LOCALLY;
|
||||
|
||||
return BEHAVE_FORWARD_ANY;
|
||||
}
|
||||
|
||||
static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (get_sanitized_cnthctl(vcpu) & (CNTHCTL_EL1PCEN << 10))
|
||||
return BEHAVE_HANDLE_LOCALLY;
|
||||
|
||||
return BEHAVE_FORWARD_ANY;
|
||||
}
|
||||
|
||||
#define CCC(id, fn) \
|
||||
[id - __COMPLEX_CONDITIONS__] = fn
|
||||
|
||||
static const complex_condition_check ccc[] = {
|
||||
CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
|
||||
CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
|
||||
};
|
||||
|
||||
/*
|
||||
@ -877,6 +920,11 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
|
||||
SR_TRAP(SYS_TRBPTR_EL1, CGT_MDCR_E2TB),
|
||||
SR_TRAP(SYS_TRBSR_EL1, CGT_MDCR_E2TB),
|
||||
SR_TRAP(SYS_TRBTRG_EL1, CGT_MDCR_E2TB),
|
||||
SR_TRAP(SYS_CNTP_TVAL_EL0, CGT_CNTHCTL_EL1PTEN),
|
||||
SR_TRAP(SYS_CNTP_CVAL_EL0, CGT_CNTHCTL_EL1PTEN),
|
||||
SR_TRAP(SYS_CNTP_CTL_EL0, CGT_CNTHCTL_EL1PTEN),
|
||||
SR_TRAP(SYS_CNTPCT_EL0, CGT_CNTHCTL_EL1PCTEN),
|
||||
SR_TRAP(SYS_CNTPCTSS_EL0, CGT_CNTHCTL_EL1PCTEN),
|
||||
};
|
||||
|
||||
static DEFINE_XARRAY(sr_forward_xa);
|
||||
|
Loading…
Reference in New Issue
Block a user