Skip to content

Commit 4fcdf10

Browse files
ionela-voinescuctmarinas
authored andcommitted
arm64/kvm: disable access to AMU registers from kvm guests
Access to the AMU counters should be disabled by default in kvm guests, as information from the counters might reveal activity in other guests or activity on the host. Therefore, disable access to AMU registers from EL0 and EL1 in kvm guests by: - Hiding the presence of the extension in the feature register (SYS_ID_AA64PFR0_EL1) on the VCPU. - Disabling access to the AMU registers before switching to the guest. - Trapping accesses and injecting an undefined instruction into the guest. Signed-off-by: Ionela Voinescu <[email protected]> Reviewed-by: Suzuki K Poulose <[email protected]> Reviewed-by: Valentin Schneider <[email protected]> Acked-by: Marc Zyngier <[email protected]> Cc: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Suzuki K Poulose <[email protected]> Cc: Julien Thierry <[email protected]> Cc: James Morse <[email protected]> Cc: Marc Zyngier <[email protected]> Signed-off-by: Catalin Marinas <[email protected]>
1 parent 87a1f06 commit 4fcdf10

File tree

3 files changed

+105
-3
lines changed

3 files changed

+105
-3
lines changed

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@
267267

268268
/* Hyp Coprocessor Trap Register */
269269
#define CPTR_EL2_TCPAC (1 << 31)
270+
#define CPTR_EL2_TAM (1 << 30)
270271
#define CPTR_EL2_TTA (1 << 20)
271272
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
272273
#define CPTR_EL2_TZ (1 << 8)

arch/arm64/kvm/hyp/switch.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,18 @@ static void activate_traps_vhe(struct kvm_vcpu *vcpu)
9898
val = read_sysreg(cpacr_el1);
9999
val |= CPACR_EL1_TTA;
100100
val &= ~CPACR_EL1_ZEN;
101+
102+
/*
103+
* With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
104+
* CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
105+
* except for some missing controls, such as TAM.
106+
* In this case, CPTR_EL2.TAM has the same position with or without
107+
* VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
108+
* shift value for trapping the AMU accesses.
109+
*/
110+
111+
val |= CPTR_EL2_TAM;
112+
101113
if (update_fp_enabled(vcpu)) {
102114
if (vcpu_has_sve(vcpu))
103115
val |= CPACR_EL1_ZEN;
@@ -119,7 +131,7 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
119131
__activate_traps_common(vcpu);
120132

121133
val = CPTR_EL2_DEFAULT;
122-
val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
134+
val |= CPTR_EL2_TTA | CPTR_EL2_TZ | CPTR_EL2_TAM;
123135
if (!update_fp_enabled(vcpu)) {
124136
val |= CPTR_EL2_TFP;
125137
__activate_traps_fpsimd32(vcpu);

arch/arm64/kvm/sys_regs.c

Lines changed: 91 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1003,6 +1003,20 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
10031003
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
10041004
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
10051005

1006+
static bool access_amu(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1007+
const struct sys_reg_desc *r)
1008+
{
1009+
kvm_inject_undefined(vcpu);
1010+
1011+
return false;
1012+
}
1013+
1014+
/* Macro to expand the AMU counter and type registers*/
1015+
#define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu }
1016+
#define AMU_AMEVTYPE0_EL0(n) { SYS_DESC(SYS_AMEVTYPE0_EL0(n)), access_amu }
1017+
#define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu }
1018+
#define AMU_AMEVTYPE1_EL0(n) { SYS_DESC(SYS_AMEVTYPE1_EL0(n)), access_amu }
1019+
10061020
static bool trap_ptrauth(struct kvm_vcpu *vcpu,
10071021
struct sys_reg_params *p,
10081022
const struct sys_reg_desc *rd)
@@ -1078,8 +1092,10 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
10781092
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
10791093
u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
10801094

1081-
if (id == SYS_ID_AA64PFR0_EL1 && !vcpu_has_sve(vcpu)) {
1082-
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
1095+
if (id == SYS_ID_AA64PFR0_EL1) {
1096+
if (!vcpu_has_sve(vcpu))
1097+
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
1098+
val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT);
10831099
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
10841100
val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) |
10851101
(0xfUL << ID_AA64ISAR1_API_SHIFT) |
@@ -1565,6 +1581,79 @@ static const struct sys_reg_desc sys_reg_descs[] = {
15651581
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
15661582
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
15671583

1584+
{ SYS_DESC(SYS_AMCR_EL0), access_amu },
1585+
{ SYS_DESC(SYS_AMCFGR_EL0), access_amu },
1586+
{ SYS_DESC(SYS_AMCGCR_EL0), access_amu },
1587+
{ SYS_DESC(SYS_AMUSERENR_EL0), access_amu },
1588+
{ SYS_DESC(SYS_AMCNTENCLR0_EL0), access_amu },
1589+
{ SYS_DESC(SYS_AMCNTENSET0_EL0), access_amu },
1590+
{ SYS_DESC(SYS_AMCNTENCLR1_EL0), access_amu },
1591+
{ SYS_DESC(SYS_AMCNTENSET1_EL0), access_amu },
1592+
AMU_AMEVCNTR0_EL0(0),
1593+
AMU_AMEVCNTR0_EL0(1),
1594+
AMU_AMEVCNTR0_EL0(2),
1595+
AMU_AMEVCNTR0_EL0(3),
1596+
AMU_AMEVCNTR0_EL0(4),
1597+
AMU_AMEVCNTR0_EL0(5),
1598+
AMU_AMEVCNTR0_EL0(6),
1599+
AMU_AMEVCNTR0_EL0(7),
1600+
AMU_AMEVCNTR0_EL0(8),
1601+
AMU_AMEVCNTR0_EL0(9),
1602+
AMU_AMEVCNTR0_EL0(10),
1603+
AMU_AMEVCNTR0_EL0(11),
1604+
AMU_AMEVCNTR0_EL0(12),
1605+
AMU_AMEVCNTR0_EL0(13),
1606+
AMU_AMEVCNTR0_EL0(14),
1607+
AMU_AMEVCNTR0_EL0(15),
1608+
AMU_AMEVTYPE0_EL0(0),
1609+
AMU_AMEVTYPE0_EL0(1),
1610+
AMU_AMEVTYPE0_EL0(2),
1611+
AMU_AMEVTYPE0_EL0(3),
1612+
AMU_AMEVTYPE0_EL0(4),
1613+
AMU_AMEVTYPE0_EL0(5),
1614+
AMU_AMEVTYPE0_EL0(6),
1615+
AMU_AMEVTYPE0_EL0(7),
1616+
AMU_AMEVTYPE0_EL0(8),
1617+
AMU_AMEVTYPE0_EL0(9),
1618+
AMU_AMEVTYPE0_EL0(10),
1619+
AMU_AMEVTYPE0_EL0(11),
1620+
AMU_AMEVTYPE0_EL0(12),
1621+
AMU_AMEVTYPE0_EL0(13),
1622+
AMU_AMEVTYPE0_EL0(14),
1623+
AMU_AMEVTYPE0_EL0(15),
1624+
AMU_AMEVCNTR1_EL0(0),
1625+
AMU_AMEVCNTR1_EL0(1),
1626+
AMU_AMEVCNTR1_EL0(2),
1627+
AMU_AMEVCNTR1_EL0(3),
1628+
AMU_AMEVCNTR1_EL0(4),
1629+
AMU_AMEVCNTR1_EL0(5),
1630+
AMU_AMEVCNTR1_EL0(6),
1631+
AMU_AMEVCNTR1_EL0(7),
1632+
AMU_AMEVCNTR1_EL0(8),
1633+
AMU_AMEVCNTR1_EL0(9),
1634+
AMU_AMEVCNTR1_EL0(10),
1635+
AMU_AMEVCNTR1_EL0(11),
1636+
AMU_AMEVCNTR1_EL0(12),
1637+
AMU_AMEVCNTR1_EL0(13),
1638+
AMU_AMEVCNTR1_EL0(14),
1639+
AMU_AMEVCNTR1_EL0(15),
1640+
AMU_AMEVTYPE1_EL0(0),
1641+
AMU_AMEVTYPE1_EL0(1),
1642+
AMU_AMEVTYPE1_EL0(2),
1643+
AMU_AMEVTYPE1_EL0(3),
1644+
AMU_AMEVTYPE1_EL0(4),
1645+
AMU_AMEVTYPE1_EL0(5),
1646+
AMU_AMEVTYPE1_EL0(6),
1647+
AMU_AMEVTYPE1_EL0(7),
1648+
AMU_AMEVTYPE1_EL0(8),
1649+
AMU_AMEVTYPE1_EL0(9),
1650+
AMU_AMEVTYPE1_EL0(10),
1651+
AMU_AMEVTYPE1_EL0(11),
1652+
AMU_AMEVTYPE1_EL0(12),
1653+
AMU_AMEVTYPE1_EL0(13),
1654+
AMU_AMEVTYPE1_EL0(14),
1655+
AMU_AMEVTYPE1_EL0(15),
1656+
15681657
{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
15691658
{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
15701659
{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },

0 commit comments

Comments
 (0)