mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
Merge branch kvm-arm64/nv-timers into kvmarm-master/next
* kvm-arm64/nv-timers:
: .
: Nested Virt support for the EL2 timers. From the initial cover letter:
:
: "Here's another batch of NV-related patches, this time bringing in most
: of the timer support for EL2 as well as nested guests.
:
: The code is pretty convoluted for a bunch of reasons:
:
: - FEAT_NV2 breaks the timer semantics by redirecting HW controls to
: memory, meaning that a guest could setup a timer and never see it
: firing until the next exit
:
: - We go try hard to reflect the timer state in memory, but that's not
: great.
:
: - With FEAT_ECV, we can finally correctly emulate the virtual timer,
: but this emulation is pretty costly
:
: - As a way to make things suck less, we handle timer reads as early as
: possible, and only defer writes to the normal trap handling
:
: - Finally, some implementations are badly broken, and require some
: hand-holding, irrespective of NV support. So we try and reuse the NV
: infrastructure to make them usable. This could be further optimised,
: but I'm running out of patience for this sort of HW.
:
: [...]"
: .
KVM: arm64: nv: Fix doc header layout for timers
KVM: arm64: nv: Document EL2 timer API
KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity
KVM: arm64: nv: Sanitise CNTHCTL_EL2
KVM: arm64: nv: Propagate CNTHCTL_EL2.EL1NV{P,V}CT bits
KVM: arm64: nv: Add trap routing for CNTHCTL_EL2.EL1{NVPCT,NVVCT,TVT,TVCT}
KVM: arm64: Handle counter access early in non-HYP context
KVM: arm64: nv: Accelerate EL0 counter accesses from hypervisor context
KVM: arm64: nv: Accelerate EL0 timer read accesses when FEAT_ECV in use
KVM: arm64: nv: Use FEAT_ECV to trap access to EL0 timers
KVM: arm64: nv: Publish emulated timer interrupt state in the in-memory state
KVM: arm64: nv: Sync nested timer state with FEAT_NV2
KVM: arm64: nv: Add handling of EL2-specific timer registers
Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
@@ -89,6 +89,9 @@ enum cgt_group_id {
|
||||
CGT_HCRX_EnFPM,
|
||||
CGT_HCRX_TCR2En,
|
||||
|
||||
CGT_CNTHCTL_EL1TVT,
|
||||
CGT_CNTHCTL_EL1TVCT,
|
||||
|
||||
CGT_ICH_HCR_TC,
|
||||
CGT_ICH_HCR_TALL0,
|
||||
CGT_ICH_HCR_TALL1,
|
||||
@@ -124,6 +127,8 @@ enum cgt_group_id {
|
||||
__COMPLEX_CONDITIONS__,
|
||||
CGT_CNTHCTL_EL1PCTEN = __COMPLEX_CONDITIONS__,
|
||||
CGT_CNTHCTL_EL1PTEN,
|
||||
CGT_CNTHCTL_EL1NVPCT,
|
||||
CGT_CNTHCTL_EL1NVVCT,
|
||||
|
||||
CGT_CPTR_TTA,
|
||||
CGT_MDCR_HPMN,
|
||||
@@ -393,6 +398,18 @@ static const struct trap_bits coarse_trap_bits[] = {
|
||||
.mask = HCRX_EL2_TCR2En,
|
||||
.behaviour = BEHAVE_FORWARD_RW,
|
||||
},
|
||||
[CGT_CNTHCTL_EL1TVT] = {
|
||||
.index = CNTHCTL_EL2,
|
||||
.value = CNTHCTL_EL1TVT,
|
||||
.mask = CNTHCTL_EL1TVT,
|
||||
.behaviour = BEHAVE_FORWARD_RW,
|
||||
},
|
||||
[CGT_CNTHCTL_EL1TVCT] = {
|
||||
.index = CNTHCTL_EL2,
|
||||
.value = CNTHCTL_EL1TVCT,
|
||||
.mask = CNTHCTL_EL1TVCT,
|
||||
.behaviour = BEHAVE_FORWARD_READ,
|
||||
},
|
||||
[CGT_ICH_HCR_TC] = {
|
||||
.index = ICH_HCR_EL2,
|
||||
.value = ICH_HCR_TC,
|
||||
@@ -487,6 +504,32 @@ static enum trap_behaviour check_cnthctl_el1pten(struct kvm_vcpu *vcpu)
|
||||
return BEHAVE_FORWARD_RW;
|
||||
}
|
||||
|
||||
static bool is_nested_nv2_guest(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 val;
|
||||
|
||||
val = __vcpu_sys_reg(vcpu, HCR_EL2);
|
||||
return ((val & (HCR_E2H | HCR_TGE | HCR_NV2 | HCR_NV1 | HCR_NV)) == (HCR_E2H | HCR_NV2 | HCR_NV));
|
||||
}
|
||||
|
||||
static enum trap_behaviour check_cnthctl_el1nvpct(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!is_nested_nv2_guest(vcpu) ||
|
||||
!(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVPCT))
|
||||
return BEHAVE_HANDLE_LOCALLY;
|
||||
|
||||
return BEHAVE_FORWARD_RW;
|
||||
}
|
||||
|
||||
static enum trap_behaviour check_cnthctl_el1nvvct(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (!is_nested_nv2_guest(vcpu) ||
|
||||
!(__vcpu_sys_reg(vcpu, CNTHCTL_EL2) & CNTHCTL_EL1NVVCT))
|
||||
return BEHAVE_HANDLE_LOCALLY;
|
||||
|
||||
return BEHAVE_FORWARD_RW;
|
||||
}
|
||||
|
||||
static enum trap_behaviour check_cptr_tta(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 val = __vcpu_sys_reg(vcpu, CPTR_EL2);
|
||||
@@ -534,6 +577,8 @@ static enum trap_behaviour check_mdcr_hpmn(struct kvm_vcpu *vcpu)
|
||||
static const complex_condition_check ccc[] = {
|
||||
CCC(CGT_CNTHCTL_EL1PCTEN, check_cnthctl_el1pcten),
|
||||
CCC(CGT_CNTHCTL_EL1PTEN, check_cnthctl_el1pten),
|
||||
CCC(CGT_CNTHCTL_EL1NVPCT, check_cnthctl_el1nvpct),
|
||||
CCC(CGT_CNTHCTL_EL1NVVCT, check_cnthctl_el1nvvct),
|
||||
CCC(CGT_CPTR_TTA, check_cptr_tta),
|
||||
CCC(CGT_MDCR_HPMN, check_mdcr_hpmn),
|
||||
};
|
||||
@@ -850,11 +895,15 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
|
||||
SYS_CNTHP_CVAL_EL2, CGT_HCR_NV),
|
||||
SR_RANGE_TRAP(SYS_CNTHV_TVAL_EL2,
|
||||
SYS_CNTHV_CVAL_EL2, CGT_HCR_NV),
|
||||
/* All _EL02, _EL12 registers */
|
||||
/* All _EL02, _EL12 registers up to CNTKCTL_EL12*/
|
||||
SR_RANGE_TRAP(sys_reg(3, 5, 0, 0, 0),
|
||||
sys_reg(3, 5, 10, 15, 7), CGT_HCR_NV),
|
||||
SR_RANGE_TRAP(sys_reg(3, 5, 12, 0, 0),
|
||||
sys_reg(3, 5, 14, 15, 7), CGT_HCR_NV),
|
||||
sys_reg(3, 5, 14, 1, 0), CGT_HCR_NV),
|
||||
SR_TRAP(SYS_CNTP_CTL_EL02, CGT_CNTHCTL_EL1NVPCT),
|
||||
SR_TRAP(SYS_CNTP_CVAL_EL02, CGT_CNTHCTL_EL1NVPCT),
|
||||
SR_TRAP(SYS_CNTV_CTL_EL02, CGT_CNTHCTL_EL1NVVCT),
|
||||
SR_TRAP(SYS_CNTV_CVAL_EL02, CGT_CNTHCTL_EL1NVVCT),
|
||||
SR_TRAP(OP_AT_S1E2R, CGT_HCR_NV),
|
||||
SR_TRAP(OP_AT_S1E2W, CGT_HCR_NV),
|
||||
SR_TRAP(OP_AT_S12E1R, CGT_HCR_NV),
|
||||
@@ -1184,6 +1233,11 @@ static const struct encoding_to_trap_config encoding_to_cgt[] __initconst = {
|
||||
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),
|
||||
SR_TRAP(SYS_CNTV_TVAL_EL0, CGT_CNTHCTL_EL1TVT),
|
||||
SR_TRAP(SYS_CNTV_CVAL_EL0, CGT_CNTHCTL_EL1TVT),
|
||||
SR_TRAP(SYS_CNTV_CTL_EL0, CGT_CNTHCTL_EL1TVT),
|
||||
SR_TRAP(SYS_CNTVCT_EL0, CGT_CNTHCTL_EL1TVCT),
|
||||
SR_TRAP(SYS_CNTVCTSS_EL0, CGT_CNTHCTL_EL1TVCT),
|
||||
SR_TRAP(SYS_FPMR, CGT_HCRX_EnFPM),
|
||||
/*
|
||||
* IMPDEF choice:
|
||||
|
||||
Reference in New Issue
Block a user