Skip to content

Commit 676f482

Browse files
Fuad TabbaMarc Zyngier
authored andcommitted
KVM: arm64: Handle HAFGRTR_EL2 trapping in nested virt
Add the encodings to fine grain trapping fields for HAFGRTR_EL2 and add the associated handling code in nested virt. Based on DDI0601 2023-09. Add the missing field definitions as well, both to generate the correct RES0 mask and to be able to toggle their FGT bits. Also add the code for handling FGT trapping, reading of the register, to nested virt. Reviewed-by: Mark Brown <broonie@kernel.org> Signed-off-by: Fuad Tabba <tabba@google.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20231214100158.2305400-10-tabba@google.com
1 parent f9d6ed0 commit 676f482

4 files changed

Lines changed: 75 additions & 0 deletions

File tree

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ enum vcpu_sysreg {
443443
HFGITR_EL2,
444444
HDFGRTR_EL2,
445445
HDFGWTR_EL2,
446+
HAFGRTR_EL2,
446447
CNTHP_CTL_EL2,
447448
CNTHP_CVAL_EL2,
448449
CNTHV_CTL_EL2,

arch/arm64/kvm/emulate-nested.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,7 @@ enum fgt_group_id {
10121012
HDFGRTR_GROUP,
10131013
HDFGWTR_GROUP,
10141014
HFGITR_GROUP,
1015+
HAFGRTR_GROUP,
10151016

10161017
/* Must be last */
10171018
__NR_FGT_GROUP_IDS__
@@ -1689,6 +1690,49 @@ static const struct encoding_to_trap_config encoding_to_fgt[] __initconst = {
16891690
SR_FGT(SYS_PMCR_EL0, HDFGWTR, PMCR_EL0, 1),
16901691
SR_FGT(SYS_PMSWINC_EL0, HDFGWTR, PMSWINC_EL0, 1),
16911692
SR_FGT(SYS_OSLAR_EL1, HDFGWTR, OSLAR_EL1, 1),
1693+
/*
1694+
* HAFGRTR_EL2
1695+
*/
1696+
SR_FGT(SYS_AMEVTYPER1_EL0(15), HAFGRTR, AMEVTYPER115_EL0, 1),
1697+
SR_FGT(SYS_AMEVTYPER1_EL0(14), HAFGRTR, AMEVTYPER114_EL0, 1),
1698+
SR_FGT(SYS_AMEVTYPER1_EL0(13), HAFGRTR, AMEVTYPER113_EL0, 1),
1699+
SR_FGT(SYS_AMEVTYPER1_EL0(12), HAFGRTR, AMEVTYPER112_EL0, 1),
1700+
SR_FGT(SYS_AMEVTYPER1_EL0(11), HAFGRTR, AMEVTYPER111_EL0, 1),
1701+
SR_FGT(SYS_AMEVTYPER1_EL0(10), HAFGRTR, AMEVTYPER110_EL0, 1),
1702+
SR_FGT(SYS_AMEVTYPER1_EL0(9), HAFGRTR, AMEVTYPER19_EL0, 1),
1703+
SR_FGT(SYS_AMEVTYPER1_EL0(8), HAFGRTR, AMEVTYPER18_EL0, 1),
1704+
SR_FGT(SYS_AMEVTYPER1_EL0(7), HAFGRTR, AMEVTYPER17_EL0, 1),
1705+
SR_FGT(SYS_AMEVTYPER1_EL0(6), HAFGRTR, AMEVTYPER16_EL0, 1),
1706+
SR_FGT(SYS_AMEVTYPER1_EL0(5), HAFGRTR, AMEVTYPER15_EL0, 1),
1707+
SR_FGT(SYS_AMEVTYPER1_EL0(4), HAFGRTR, AMEVTYPER14_EL0, 1),
1708+
SR_FGT(SYS_AMEVTYPER1_EL0(3), HAFGRTR, AMEVTYPER13_EL0, 1),
1709+
SR_FGT(SYS_AMEVTYPER1_EL0(2), HAFGRTR, AMEVTYPER12_EL0, 1),
1710+
SR_FGT(SYS_AMEVTYPER1_EL0(1), HAFGRTR, AMEVTYPER11_EL0, 1),
1711+
SR_FGT(SYS_AMEVTYPER1_EL0(0), HAFGRTR, AMEVTYPER10_EL0, 1),
1712+
SR_FGT(SYS_AMEVCNTR1_EL0(15), HAFGRTR, AMEVCNTR115_EL0, 1),
1713+
SR_FGT(SYS_AMEVCNTR1_EL0(14), HAFGRTR, AMEVCNTR114_EL0, 1),
1714+
SR_FGT(SYS_AMEVCNTR1_EL0(13), HAFGRTR, AMEVCNTR113_EL0, 1),
1715+
SR_FGT(SYS_AMEVCNTR1_EL0(12), HAFGRTR, AMEVCNTR112_EL0, 1),
1716+
SR_FGT(SYS_AMEVCNTR1_EL0(11), HAFGRTR, AMEVCNTR111_EL0, 1),
1717+
SR_FGT(SYS_AMEVCNTR1_EL0(10), HAFGRTR, AMEVCNTR110_EL0, 1),
1718+
SR_FGT(SYS_AMEVCNTR1_EL0(9), HAFGRTR, AMEVCNTR19_EL0, 1),
1719+
SR_FGT(SYS_AMEVCNTR1_EL0(8), HAFGRTR, AMEVCNTR18_EL0, 1),
1720+
SR_FGT(SYS_AMEVCNTR1_EL0(7), HAFGRTR, AMEVCNTR17_EL0, 1),
1721+
SR_FGT(SYS_AMEVCNTR1_EL0(6), HAFGRTR, AMEVCNTR16_EL0, 1),
1722+
SR_FGT(SYS_AMEVCNTR1_EL0(5), HAFGRTR, AMEVCNTR15_EL0, 1),
1723+
SR_FGT(SYS_AMEVCNTR1_EL0(4), HAFGRTR, AMEVCNTR14_EL0, 1),
1724+
SR_FGT(SYS_AMEVCNTR1_EL0(3), HAFGRTR, AMEVCNTR13_EL0, 1),
1725+
SR_FGT(SYS_AMEVCNTR1_EL0(2), HAFGRTR, AMEVCNTR12_EL0, 1),
1726+
SR_FGT(SYS_AMEVCNTR1_EL0(1), HAFGRTR, AMEVCNTR11_EL0, 1),
1727+
SR_FGT(SYS_AMEVCNTR1_EL0(0), HAFGRTR, AMEVCNTR10_EL0, 1),
1728+
SR_FGT(SYS_AMCNTENCLR1_EL0, HAFGRTR, AMCNTEN1, 1),
1729+
SR_FGT(SYS_AMCNTENSET1_EL0, HAFGRTR, AMCNTEN1, 1),
1730+
SR_FGT(SYS_AMCNTENCLR0_EL0, HAFGRTR, AMCNTEN0, 1),
1731+
SR_FGT(SYS_AMCNTENSET0_EL0, HAFGRTR, AMCNTEN0, 1),
1732+
SR_FGT(SYS_AMEVCNTR0_EL0(3), HAFGRTR, AMEVCNTR03_EL0, 1),
1733+
SR_FGT(SYS_AMEVCNTR0_EL0(2), HAFGRTR, AMEVCNTR02_EL0, 1),
1734+
SR_FGT(SYS_AMEVCNTR0_EL0(1), HAFGRTR, AMEVCNTR01_EL0, 1),
1735+
SR_FGT(SYS_AMEVCNTR0_EL0(0), HAFGRTR, AMEVCNTR00_EL0, 1),
16921736
};
16931737

16941738
static union trap_config get_trap_config(u32 sysreg)
@@ -1909,6 +1953,10 @@ bool __check_nv_sr_forward(struct kvm_vcpu *vcpu)
19091953
val = sanitised_sys_reg(vcpu, HDFGWTR_EL2);
19101954
break;
19111955

1956+
case HAFGRTR_GROUP:
1957+
val = sanitised_sys_reg(vcpu, HAFGRTR_EL2);
1958+
break;
1959+
19121960
case HFGITR_GROUP:
19131961
val = sanitised_sys_reg(vcpu, HFGITR_EL2);
19141962
switch (tc.fgf) {

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
8080
} while(0)
8181

8282

83+
static inline bool cpu_has_amu(void)
84+
{
85+
u64 pfr0 = read_sysreg_s(SYS_ID_AA64PFR0_EL1);
86+
87+
return cpuid_feature_extract_unsigned_field(pfr0,
88+
ID_AA64PFR0_EL1_AMU_SHIFT);
89+
}
90+
8391
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
8492
{
8593
struct kvm_cpu_context *hctxt = &this_cpu_ptr(&kvm_host_data)->host_ctxt;
@@ -156,6 +164,20 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
156164

157165
write_sysreg_s(r_val, SYS_HDFGRTR_EL2);
158166
write_sysreg_s(w_val, SYS_HDFGWTR_EL2);
167+
168+
if (!cpu_has_amu())
169+
return;
170+
171+
ctxt_sys_reg(hctxt, HAFGRTR_EL2) = read_sysreg_s(SYS_HAFGRTR_EL2);
172+
173+
r_clr = r_set = 0;
174+
compute_clr_set(vcpu, HAFGRTR_EL2, r_clr, r_set);
175+
176+
r_val = __HAFGRTR_EL2_nMASK;
177+
r_val |= r_set;
178+
r_val &= ~r_clr;
179+
180+
write_sysreg_s(r_val, SYS_HAFGRTR_EL2);
159181
}
160182

161183
static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
@@ -174,6 +196,9 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
174196
write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
175197
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
176198
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
199+
200+
if (vcpu_has_amu())
201+
write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2);
177202
}
178203

179204
static inline void __activate_traps_common(struct kvm_vcpu *vcpu)

arch/arm64/kvm/sys_regs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2532,6 +2532,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {
25322532
{ SYS_DESC(SYS_DACR32_EL2), trap_undef, reset_unknown, DACR32_EL2 },
25332533
EL2_REG(HDFGRTR_EL2, access_rw, reset_val, 0),
25342534
EL2_REG(HDFGWTR_EL2, access_rw, reset_val, 0),
2535+
EL2_REG(HAFGRTR_EL2, access_rw, reset_val, 0),
25352536
EL2_REG(SPSR_EL2, access_rw, reset_val, 0),
25362537
EL2_REG(ELR_EL2, access_rw, reset_val, 0),
25372538
{ SYS_DESC(SYS_SP_EL1), access_sp_el1},

0 commit comments

Comments
 (0)