Skip to content

Commit 4a999a1

Browse files
author
Marc Zyngier
committed
KVM: arm64: Make most GICv3 accesses UNDEF if they trap
We don't expect to trap any GICv3 register for host handling, apart from ICC_SRE_EL1 and the SGI registers. If they trap, that's because the guest is playing with us despite being told it doesn't have a GICv3. If it does, UNDEF is what it will get. Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 59af011 commit 4a999a1

File tree

3 files changed

+66
-18
lines changed

3 files changed

+66
-18
lines changed

arch/arm64/kvm/hyp/vgic-v3-sr.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,9 @@ int __vgic_v3_perform_cpuif_access(struct kvm_vcpu *vcpu)
11201120
bool is_read;
11211121
u32 sysreg;
11221122

1123+
if (kern_hyp_va(vcpu->kvm)->arch.vgic.vgic_model != KVM_DEV_TYPE_ARM_VGIC_V3)
1124+
return 0;
1125+
11231126
esr = kvm_vcpu_get_esr(vcpu);
11241127
if (vcpu_mode_is_32bit(vcpu)) {
11251128
if (!kvm_condition_valid(vcpu)) {

arch/arm64/kvm/sys_regs.c

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ static u64 sys_reg_to_index(const struct sys_reg_desc *reg);
4747
static int set_id_reg(struct kvm_vcpu *vcpu, const struct sys_reg_desc *rd,
4848
u64 val);
4949

50+
static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
51+
const struct sys_reg_desc *r)
52+
{
53+
kvm_inject_undefined(vcpu);
54+
return false;
55+
}
56+
5057
static bool bad_trap(struct kvm_vcpu *vcpu,
5158
struct sys_reg_params *params,
5259
const struct sys_reg_desc *r,
@@ -484,6 +491,9 @@ static bool access_gic_sre(struct kvm_vcpu *vcpu,
484491
struct sys_reg_params *p,
485492
const struct sys_reg_desc *r)
486493
{
494+
if (!kvm_has_gicv3(vcpu->kvm))
495+
return undef_access(vcpu, p, r);
496+
487497
if (p->is_write)
488498
return ignore_write(vcpu, p);
489499

@@ -1344,14 +1354,6 @@ static int set_pmcr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r,
13441354
.reset = reset_pmevtyper, \
13451355
.access = access_pmu_evtyper, .reg = (PMEVTYPER0_EL0 + n), }
13461356

1347-
static bool undef_access(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
1348-
const struct sys_reg_desc *r)
1349-
{
1350-
kvm_inject_undefined(vcpu);
1351-
1352-
return false;
1353-
}
1354-
13551357
/* Macro to expand the AMU counter and type registers*/
13561358
#define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), undef_access }
13571359
#define AMU_AMEVTYPER0_EL0(n) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), undef_access }
@@ -2454,6 +2456,8 @@ static const struct sys_reg_desc sys_reg_descs[] = {
24542456
{ SYS_DESC(SYS_SPSR_EL1), access_spsr},
24552457
{ SYS_DESC(SYS_ELR_EL1), access_elr},
24562458

2459+
{ SYS_DESC(SYS_ICC_PMR_EL1), undef_access },
2460+
24572461
{ SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 },
24582462
{ SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 },
24592463
{ SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 },
@@ -2508,18 +2512,31 @@ static const struct sys_reg_desc sys_reg_descs[] = {
25082512
{ SYS_DESC(SYS_VBAR_EL1), access_rw, reset_val, VBAR_EL1, 0 },
25092513
{ SYS_DESC(SYS_DISR_EL1), NULL, reset_val, DISR_EL1, 0 },
25102514

2511-
{ SYS_DESC(SYS_ICC_IAR0_EL1), write_to_read_only },
2512-
{ SYS_DESC(SYS_ICC_EOIR0_EL1), read_from_write_only },
2513-
{ SYS_DESC(SYS_ICC_HPPIR0_EL1), write_to_read_only },
2514-
{ SYS_DESC(SYS_ICC_DIR_EL1), read_from_write_only },
2515-
{ SYS_DESC(SYS_ICC_RPR_EL1), write_to_read_only },
2515+
{ SYS_DESC(SYS_ICC_IAR0_EL1), undef_access },
2516+
{ SYS_DESC(SYS_ICC_EOIR0_EL1), undef_access },
2517+
{ SYS_DESC(SYS_ICC_HPPIR0_EL1), undef_access },
2518+
{ SYS_DESC(SYS_ICC_BPR0_EL1), undef_access },
2519+
{ SYS_DESC(SYS_ICC_AP0R0_EL1), undef_access },
2520+
{ SYS_DESC(SYS_ICC_AP0R1_EL1), undef_access },
2521+
{ SYS_DESC(SYS_ICC_AP0R2_EL1), undef_access },
2522+
{ SYS_DESC(SYS_ICC_AP0R3_EL1), undef_access },
2523+
{ SYS_DESC(SYS_ICC_AP1R0_EL1), undef_access },
2524+
{ SYS_DESC(SYS_ICC_AP1R1_EL1), undef_access },
2525+
{ SYS_DESC(SYS_ICC_AP1R2_EL1), undef_access },
2526+
{ SYS_DESC(SYS_ICC_AP1R3_EL1), undef_access },
2527+
{ SYS_DESC(SYS_ICC_DIR_EL1), undef_access },
2528+
{ SYS_DESC(SYS_ICC_RPR_EL1), undef_access },
25162529
{ SYS_DESC(SYS_ICC_SGI1R_EL1), access_gic_sgi },
25172530
{ SYS_DESC(SYS_ICC_ASGI1R_EL1), access_gic_sgi },
25182531
{ SYS_DESC(SYS_ICC_SGI0R_EL1), access_gic_sgi },
2519-
{ SYS_DESC(SYS_ICC_IAR1_EL1), write_to_read_only },
2520-
{ SYS_DESC(SYS_ICC_EOIR1_EL1), read_from_write_only },
2521-
{ SYS_DESC(SYS_ICC_HPPIR1_EL1), write_to_read_only },
2532+
{ SYS_DESC(SYS_ICC_IAR1_EL1), undef_access },
2533+
{ SYS_DESC(SYS_ICC_EOIR1_EL1), undef_access },
2534+
{ SYS_DESC(SYS_ICC_HPPIR1_EL1), undef_access },
2535+
{ SYS_DESC(SYS_ICC_BPR1_EL1), undef_access },
2536+
{ SYS_DESC(SYS_ICC_CTLR_EL1), undef_access },
25222537
{ SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre },
2538+
{ SYS_DESC(SYS_ICC_IGRPEN0_EL1), undef_access },
2539+
{ SYS_DESC(SYS_ICC_IGRPEN1_EL1), undef_access },
25232540

25242541
{ SYS_DESC(SYS_CONTEXTIDR_EL1), access_vm_reg, reset_val, CONTEXTIDR_EL1, 0 },
25252542
{ SYS_DESC(SYS_TPIDR_EL1), NULL, reset_unknown, TPIDR_EL1 },
@@ -3394,6 +3411,7 @@ static const struct sys_reg_desc cp15_regs[] = {
33943411
/* TTBCR2 */
33953412
{ AA32(HI), Op1( 0), CRn( 2), CRm( 0), Op2( 3), access_vm_reg, NULL, TCR_EL1 },
33963413
{ Op1( 0), CRn( 3), CRm( 0), Op2( 0), access_vm_reg, NULL, DACR32_EL2 },
3414+
{ CP15_SYS_DESC(SYS_ICC_PMR_EL1), undef_access },
33973415
/* DFSR */
33983416
{ Op1( 0), CRn( 5), CRm( 0), Op2( 0), access_vm_reg, NULL, ESR_EL1 },
33993417
{ Op1( 0), CRn( 5), CRm( 0), Op2( 1), access_vm_reg, NULL, IFSR32_EL2 },
@@ -3443,8 +3461,28 @@ static const struct sys_reg_desc cp15_regs[] = {
34433461
/* AMAIR1 */
34443462
{ AA32(HI), Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, AMAIR_EL1 },
34453463

3446-
/* ICC_SRE */
3447-
{ Op1( 0), CRn(12), CRm(12), Op2( 5), access_gic_sre },
3464+
{ CP15_SYS_DESC(SYS_ICC_IAR0_EL1), undef_access },
3465+
{ CP15_SYS_DESC(SYS_ICC_EOIR0_EL1), undef_access },
3466+
{ CP15_SYS_DESC(SYS_ICC_HPPIR0_EL1), undef_access },
3467+
{ CP15_SYS_DESC(SYS_ICC_BPR0_EL1), undef_access },
3468+
{ CP15_SYS_DESC(SYS_ICC_AP0R0_EL1), undef_access },
3469+
{ CP15_SYS_DESC(SYS_ICC_AP0R1_EL1), undef_access },
3470+
{ CP15_SYS_DESC(SYS_ICC_AP0R2_EL1), undef_access },
3471+
{ CP15_SYS_DESC(SYS_ICC_AP0R3_EL1), undef_access },
3472+
{ CP15_SYS_DESC(SYS_ICC_AP1R0_EL1), undef_access },
3473+
{ CP15_SYS_DESC(SYS_ICC_AP1R1_EL1), undef_access },
3474+
{ CP15_SYS_DESC(SYS_ICC_AP1R2_EL1), undef_access },
3475+
{ CP15_SYS_DESC(SYS_ICC_AP1R3_EL1), undef_access },
3476+
{ CP15_SYS_DESC(SYS_ICC_DIR_EL1), undef_access },
3477+
{ CP15_SYS_DESC(SYS_ICC_RPR_EL1), undef_access },
3478+
{ CP15_SYS_DESC(SYS_ICC_IAR1_EL1), undef_access },
3479+
{ CP15_SYS_DESC(SYS_ICC_EOIR1_EL1), undef_access },
3480+
{ CP15_SYS_DESC(SYS_ICC_HPPIR1_EL1), undef_access },
3481+
{ CP15_SYS_DESC(SYS_ICC_BPR1_EL1), undef_access },
3482+
{ CP15_SYS_DESC(SYS_ICC_CTLR_EL1), undef_access },
3483+
{ CP15_SYS_DESC(SYS_ICC_SRE_EL1), access_gic_sre },
3484+
{ CP15_SYS_DESC(SYS_ICC_IGRPEN0_EL1), undef_access },
3485+
{ CP15_SYS_DESC(SYS_ICC_IGRPEN1_EL1), undef_access },
34483486

34493487
{ Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, CONTEXTIDR_EL1 },
34503488

arch/arm64/kvm/sys_regs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,11 @@ int kvm_finalize_sys_regs(struct kvm_vcpu *vcpu);
250250
CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \
251251
Op2(sys_reg_Op2(reg))
252252

253+
#define CP15_SYS_DESC(reg) \
254+
.name = #reg, \
255+
.aarch32_map = AA32_DIRECT, \
256+
Op0(0), Op1(sys_reg_Op1(reg)), \
257+
CRn(sys_reg_CRn(reg)), CRm(sys_reg_CRm(reg)), \
258+
Op2(sys_reg_Op2(reg))
259+
253260
#endif /* __ARM64_KVM_SYS_REGS_LOCAL_H__ */

0 commit comments

Comments
 (0)