mirror of https://gitee.com/openkylin/linux.git
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 <ionela.voinescu@arm.com> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Reviewed-by: Valentin Schneider <valentin.schneider@arm.com> Acked-by: Marc Zyngier <maz@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Suzuki K Poulose <suzuki.poulose@arm.com> Cc: Julien Thierry <julien.thierry.kdev@gmail.com> Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
87a1f06346
commit
4fcdf106a4
|
@ -267,6 +267,7 @@
|
||||||
|
|
||||||
/* Hyp Coprocessor Trap Register */
|
/* Hyp Coprocessor Trap Register */
|
||||||
#define CPTR_EL2_TCPAC (1 << 31)
|
#define CPTR_EL2_TCPAC (1 << 31)
|
||||||
|
#define CPTR_EL2_TAM (1 << 30)
|
||||||
#define CPTR_EL2_TTA (1 << 20)
|
#define CPTR_EL2_TTA (1 << 20)
|
||||||
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
|
#define CPTR_EL2_TFP (1 << CPTR_EL2_TFP_SHIFT)
|
||||||
#define CPTR_EL2_TZ (1 << 8)
|
#define CPTR_EL2_TZ (1 << 8)
|
||||||
|
|
|
@ -98,6 +98,18 @@ static void activate_traps_vhe(struct kvm_vcpu *vcpu)
|
||||||
val = read_sysreg(cpacr_el1);
|
val = read_sysreg(cpacr_el1);
|
||||||
val |= CPACR_EL1_TTA;
|
val |= CPACR_EL1_TTA;
|
||||||
val &= ~CPACR_EL1_ZEN;
|
val &= ~CPACR_EL1_ZEN;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
|
||||||
|
* CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
|
||||||
|
* except for some missing controls, such as TAM.
|
||||||
|
* In this case, CPTR_EL2.TAM has the same position with or without
|
||||||
|
* VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
|
||||||
|
* shift value for trapping the AMU accesses.
|
||||||
|
*/
|
||||||
|
|
||||||
|
val |= CPTR_EL2_TAM;
|
||||||
|
|
||||||
if (update_fp_enabled(vcpu)) {
|
if (update_fp_enabled(vcpu)) {
|
||||||
if (vcpu_has_sve(vcpu))
|
if (vcpu_has_sve(vcpu))
|
||||||
val |= CPACR_EL1_ZEN;
|
val |= CPACR_EL1_ZEN;
|
||||||
|
@ -119,7 +131,7 @@ static void __hyp_text __activate_traps_nvhe(struct kvm_vcpu *vcpu)
|
||||||
__activate_traps_common(vcpu);
|
__activate_traps_common(vcpu);
|
||||||
|
|
||||||
val = CPTR_EL2_DEFAULT;
|
val = CPTR_EL2_DEFAULT;
|
||||||
val |= CPTR_EL2_TTA | CPTR_EL2_TZ;
|
val |= CPTR_EL2_TTA | CPTR_EL2_TZ | CPTR_EL2_TAM;
|
||||||
if (!update_fp_enabled(vcpu)) {
|
if (!update_fp_enabled(vcpu)) {
|
||||||
val |= CPTR_EL2_TFP;
|
val |= CPTR_EL2_TFP;
|
||||||
__activate_traps_fpsimd32(vcpu);
|
__activate_traps_fpsimd32(vcpu);
|
||||||
|
|
|
@ -1003,6 +1003,20 @@ static bool access_pmuserenr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
||||||
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
|
{ SYS_DESC(SYS_PMEVTYPERn_EL0(n)), \
|
||||||
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
|
access_pmu_evtyper, reset_unknown, (PMEVTYPER0_EL0 + n), }
|
||||||
|
|
||||||
|
static bool access_amu(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
||||||
|
const struct sys_reg_desc *r)
|
||||||
|
{
|
||||||
|
kvm_inject_undefined(vcpu);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Macro to expand the AMU counter and type registers*/
|
||||||
|
#define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu }
|
||||||
|
#define AMU_AMEVTYPE0_EL0(n) { SYS_DESC(SYS_AMEVTYPE0_EL0(n)), access_amu }
|
||||||
|
#define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu }
|
||||||
|
#define AMU_AMEVTYPE1_EL0(n) { SYS_DESC(SYS_AMEVTYPE1_EL0(n)), access_amu }
|
||||||
|
|
||||||
static bool trap_ptrauth(struct kvm_vcpu *vcpu,
|
static bool trap_ptrauth(struct kvm_vcpu *vcpu,
|
||||||
struct sys_reg_params *p,
|
struct sys_reg_params *p,
|
||||||
const struct sys_reg_desc *rd)
|
const struct sys_reg_desc *rd)
|
||||||
|
@ -1078,8 +1092,10 @@ static u64 read_id_reg(const struct kvm_vcpu *vcpu,
|
||||||
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
|
(u32)r->CRn, (u32)r->CRm, (u32)r->Op2);
|
||||||
u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
|
u64 val = raz ? 0 : read_sanitised_ftr_reg(id);
|
||||||
|
|
||||||
if (id == SYS_ID_AA64PFR0_EL1 && !vcpu_has_sve(vcpu)) {
|
if (id == SYS_ID_AA64PFR0_EL1) {
|
||||||
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
|
if (!vcpu_has_sve(vcpu))
|
||||||
|
val &= ~(0xfUL << ID_AA64PFR0_SVE_SHIFT);
|
||||||
|
val &= ~(0xfUL << ID_AA64PFR0_AMU_SHIFT);
|
||||||
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
|
} else if (id == SYS_ID_AA64ISAR1_EL1 && !vcpu_has_ptrauth(vcpu)) {
|
||||||
val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) |
|
val &= ~((0xfUL << ID_AA64ISAR1_APA_SHIFT) |
|
||||||
(0xfUL << ID_AA64ISAR1_API_SHIFT) |
|
(0xfUL << ID_AA64ISAR1_API_SHIFT) |
|
||||||
|
@ -1565,6 +1581,79 @@ static const struct sys_reg_desc sys_reg_descs[] = {
|
||||||
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
|
{ SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 },
|
||||||
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
|
{ SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 },
|
||||||
|
|
||||||
|
{ SYS_DESC(SYS_AMCR_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCFGR_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCGCR_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMUSERENR_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCNTENCLR0_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCNTENSET0_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCNTENCLR1_EL0), access_amu },
|
||||||
|
{ SYS_DESC(SYS_AMCNTENSET1_EL0), access_amu },
|
||||||
|
AMU_AMEVCNTR0_EL0(0),
|
||||||
|
AMU_AMEVCNTR0_EL0(1),
|
||||||
|
AMU_AMEVCNTR0_EL0(2),
|
||||||
|
AMU_AMEVCNTR0_EL0(3),
|
||||||
|
AMU_AMEVCNTR0_EL0(4),
|
||||||
|
AMU_AMEVCNTR0_EL0(5),
|
||||||
|
AMU_AMEVCNTR0_EL0(6),
|
||||||
|
AMU_AMEVCNTR0_EL0(7),
|
||||||
|
AMU_AMEVCNTR0_EL0(8),
|
||||||
|
AMU_AMEVCNTR0_EL0(9),
|
||||||
|
AMU_AMEVCNTR0_EL0(10),
|
||||||
|
AMU_AMEVCNTR0_EL0(11),
|
||||||
|
AMU_AMEVCNTR0_EL0(12),
|
||||||
|
AMU_AMEVCNTR0_EL0(13),
|
||||||
|
AMU_AMEVCNTR0_EL0(14),
|
||||||
|
AMU_AMEVCNTR0_EL0(15),
|
||||||
|
AMU_AMEVTYPE0_EL0(0),
|
||||||
|
AMU_AMEVTYPE0_EL0(1),
|
||||||
|
AMU_AMEVTYPE0_EL0(2),
|
||||||
|
AMU_AMEVTYPE0_EL0(3),
|
||||||
|
AMU_AMEVTYPE0_EL0(4),
|
||||||
|
AMU_AMEVTYPE0_EL0(5),
|
||||||
|
AMU_AMEVTYPE0_EL0(6),
|
||||||
|
AMU_AMEVTYPE0_EL0(7),
|
||||||
|
AMU_AMEVTYPE0_EL0(8),
|
||||||
|
AMU_AMEVTYPE0_EL0(9),
|
||||||
|
AMU_AMEVTYPE0_EL0(10),
|
||||||
|
AMU_AMEVTYPE0_EL0(11),
|
||||||
|
AMU_AMEVTYPE0_EL0(12),
|
||||||
|
AMU_AMEVTYPE0_EL0(13),
|
||||||
|
AMU_AMEVTYPE0_EL0(14),
|
||||||
|
AMU_AMEVTYPE0_EL0(15),
|
||||||
|
AMU_AMEVCNTR1_EL0(0),
|
||||||
|
AMU_AMEVCNTR1_EL0(1),
|
||||||
|
AMU_AMEVCNTR1_EL0(2),
|
||||||
|
AMU_AMEVCNTR1_EL0(3),
|
||||||
|
AMU_AMEVCNTR1_EL0(4),
|
||||||
|
AMU_AMEVCNTR1_EL0(5),
|
||||||
|
AMU_AMEVCNTR1_EL0(6),
|
||||||
|
AMU_AMEVCNTR1_EL0(7),
|
||||||
|
AMU_AMEVCNTR1_EL0(8),
|
||||||
|
AMU_AMEVCNTR1_EL0(9),
|
||||||
|
AMU_AMEVCNTR1_EL0(10),
|
||||||
|
AMU_AMEVCNTR1_EL0(11),
|
||||||
|
AMU_AMEVCNTR1_EL0(12),
|
||||||
|
AMU_AMEVCNTR1_EL0(13),
|
||||||
|
AMU_AMEVCNTR1_EL0(14),
|
||||||
|
AMU_AMEVCNTR1_EL0(15),
|
||||||
|
AMU_AMEVTYPE1_EL0(0),
|
||||||
|
AMU_AMEVTYPE1_EL0(1),
|
||||||
|
AMU_AMEVTYPE1_EL0(2),
|
||||||
|
AMU_AMEVTYPE1_EL0(3),
|
||||||
|
AMU_AMEVTYPE1_EL0(4),
|
||||||
|
AMU_AMEVTYPE1_EL0(5),
|
||||||
|
AMU_AMEVTYPE1_EL0(6),
|
||||||
|
AMU_AMEVTYPE1_EL0(7),
|
||||||
|
AMU_AMEVTYPE1_EL0(8),
|
||||||
|
AMU_AMEVTYPE1_EL0(9),
|
||||||
|
AMU_AMEVTYPE1_EL0(10),
|
||||||
|
AMU_AMEVTYPE1_EL0(11),
|
||||||
|
AMU_AMEVTYPE1_EL0(12),
|
||||||
|
AMU_AMEVTYPE1_EL0(13),
|
||||||
|
AMU_AMEVTYPE1_EL0(14),
|
||||||
|
AMU_AMEVTYPE1_EL0(15),
|
||||||
|
|
||||||
{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
|
{ SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer },
|
||||||
{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
|
{ SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer },
|
||||||
{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },
|
{ SYS_DESC(SYS_CNTP_CVAL_EL0), access_arch_timer },
|
||||||
|
|
Loading…
Reference in New Issue