mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 02:53:36 +02:00
KVM: arm64: Move CNT*CT_EL0 userspace accessors to generic infrastructure
Moving the counter registers is a bit more involved than for the control and comparator (there is no shadow data for the counter), but still pretty manageable. Reviewed-by: Joey Gouly <joey.gouly@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
parent
8af198980e
commit
c3be3a48fb
|
|
@ -592,19 +592,12 @@ static unsigned long num_core_regs(const struct kvm_vcpu *vcpu)
|
|||
}
|
||||
|
||||
static const u64 timer_reg_list[] = {
|
||||
KVM_REG_ARM_TIMER_CNT,
|
||||
KVM_REG_ARM_PTIMER_CNT,
|
||||
};
|
||||
|
||||
#define NUM_TIMER_REGS ARRAY_SIZE(timer_reg_list)
|
||||
|
||||
static bool is_timer_reg(u64 index)
|
||||
{
|
||||
switch (index) {
|
||||
case KVM_REG_ARM_TIMER_CNT:
|
||||
case KVM_REG_ARM_PTIMER_CNT:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1605,12 +1605,38 @@ static int arch_timer_set_user(struct kvm_vcpu *vcpu,
|
|||
case SYS_CNTHP_CTL_EL2:
|
||||
val &= ~ARCH_TIMER_CTRL_IT_STAT;
|
||||
break;
|
||||
case SYS_CNTVCT_EL0:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags))
|
||||
timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read() - val);
|
||||
return 0;
|
||||
case SYS_CNTPCT_EL0:
|
||||
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags))
|
||||
timer_set_offset(vcpu_ptimer(vcpu), kvm_phys_timer_read() - val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__vcpu_assign_sys_reg(vcpu, rd->reg, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arch_timer_get_user(struct kvm_vcpu *vcpu,
|
||||
const struct sys_reg_desc *rd,
|
||||
u64 *val)
|
||||
{
|
||||
switch (reg_to_encoding(rd)) {
|
||||
case SYS_CNTVCT_EL0:
|
||||
*val = kvm_phys_timer_read() - timer_get_offset(vcpu_vtimer(vcpu));
|
||||
break;
|
||||
case SYS_CNTPCT_EL0:
|
||||
*val = kvm_phys_timer_read() - timer_get_offset(vcpu_ptimer(vcpu));
|
||||
break;
|
||||
default:
|
||||
*val = __vcpu_sys_reg(vcpu, rd->reg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s64 kvm_arm64_ftr_safe_value(u32 id, const struct arm64_ftr_bits *ftrp,
|
||||
s64 new, s64 cur)
|
||||
{
|
||||
|
|
@ -2539,7 +2565,7 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
|
|||
|
||||
#define TIMER_REG(name, vis) \
|
||||
SYS_REG_USER_FILTER(name, access_arch_timer, reset_val, 0, \
|
||||
NULL, arch_timer_set_user, vis)
|
||||
arch_timer_get_user, arch_timer_set_user, vis)
|
||||
|
||||
/*
|
||||
* Since reset() callback and field val are not used for idregs, they will be
|
||||
|
|
@ -3506,8 +3532,10 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
|||
AMU_AMEVTYPER1_EL0(14),
|
||||
AMU_AMEVTYPER1_EL0(15),
|
||||
|
||||
{ SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTVCT_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTPCT_EL0), .access = access_arch_timer,
|
||||
.get_user = arch_timer_get_user, .set_user = arch_timer_set_user },
|
||||
{ SYS_DESC(SYS_CNTVCT_EL0), .access = access_arch_timer,
|
||||
.get_user = arch_timer_get_user, .set_user = arch_timer_set_user },
|
||||
{ SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTVCTSS_EL0), access_arch_timer },
|
||||
{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user