Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+31 -10
-7
arch/arm64/kvm/guest.c
··· 592 592 } 593 593 594 594 static const u64 timer_reg_list[] = { 595 - KVM_REG_ARM_TIMER_CNT, 596 - KVM_REG_ARM_PTIMER_CNT, 597 595 }; 598 596 599 597 #define NUM_TIMER_REGS ARRAY_SIZE(timer_reg_list) 600 598 601 599 static bool is_timer_reg(u64 index) 602 600 { 603 - switch (index) { 604 - case KVM_REG_ARM_TIMER_CNT: 605 - case KVM_REG_ARM_PTIMER_CNT: 606 - return true; 607 - } 608 601 return false; 609 602 } 610 603
+31 -3
arch/arm64/kvm/sys_regs.c
··· 1605 1605 case SYS_CNTHP_CTL_EL2: 1606 1606 val &= ~ARCH_TIMER_CTRL_IT_STAT; 1607 1607 break; 1608 + case SYS_CNTVCT_EL0: 1609 + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) 1610 + timer_set_offset(vcpu_vtimer(vcpu), kvm_phys_timer_read() - val); 1611 + return 0; 1612 + case SYS_CNTPCT_EL0: 1613 + if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET, &vcpu->kvm->arch.flags)) 1614 + timer_set_offset(vcpu_ptimer(vcpu), kvm_phys_timer_read() - val); 1615 + return 0; 1608 1616 } 1609 1617 1610 1618 __vcpu_assign_sys_reg(vcpu, rd->reg, val); 1619 + return 0; 1620 + } 1621 + 1622 + static int arch_timer_get_user(struct kvm_vcpu *vcpu, 1623 + const struct sys_reg_desc *rd, 1624 + u64 *val) 1625 + { 1626 + switch (reg_to_encoding(rd)) { 1627 + case SYS_CNTVCT_EL0: 1628 + *val = kvm_phys_timer_read() - timer_get_offset(vcpu_vtimer(vcpu)); 1629 + break; 1630 + case SYS_CNTPCT_EL0: 1631 + *val = kvm_phys_timer_read() - timer_get_offset(vcpu_ptimer(vcpu)); 1632 + break; 1633 + default: 1634 + *val = __vcpu_sys_reg(vcpu, rd->reg); 1635 + } 1636 + 1611 1637 return 0; 1612 1638 } 1613 1639 ··· 2565 2539 2566 2540 #define TIMER_REG(name, vis) \ 2567 2541 SYS_REG_USER_FILTER(name, access_arch_timer, reset_val, 0, \ 2568 - NULL, arch_timer_set_user, vis) 2542 + arch_timer_get_user, arch_timer_set_user, vis) 2569 2543 2570 2544 /* 2571 2545 * Since reset() callback and field val are not used for idregs, they will be ··· 3532 3506 AMU_AMEVTYPER1_EL0(14), 3533 3507 AMU_AMEVTYPER1_EL0(15), 3534 3508 3535 - { SYS_DESC(SYS_CNTPCT_EL0), access_arch_timer }, 3536 - { SYS_DESC(SYS_CNTVCT_EL0), access_arch_timer }, 3509 + { SYS_DESC(SYS_CNTPCT_EL0), .access = access_arch_timer, 3510 + .get_user = arch_timer_get_user, .set_user = arch_timer_set_user }, 3511 + { SYS_DESC(SYS_CNTVCT_EL0), .access = access_arch_timer, 3512 + .get_user = arch_timer_get_user, .set_user = arch_timer_set_user }, 3537 3513 { SYS_DESC(SYS_CNTPCTSS_EL0), access_arch_timer }, 3538 3514 { SYS_DESC(SYS_CNTVCTSS_EL0), access_arch_timer }, 3539 3515 { SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },