Skip to content

Commit 3f9eacf

Browse files
author
Marc Zyngier
committed
KVM: arm64: Make all 32bit ID registers fully writable
32bit ID registers aren't getting much love these days, and are often missed in updates. One of these updates broke restoring a GICv2 guest on a GICv3 machine. Instead of performing a piecemeal fix, just bite the bullet and make all 32bit ID regs fully writable. KVM itself never relies on them for anything, and if the VMM wants to mess up the guest, so be it. Fixes: 5cb57a1 ("KVM: arm64: Zero ID_AA64PFR0_EL1.GIC when no GICv3 is presented to the guest") Reported-by: Peter Maydell <peter.maydell@linaro.org> Cc: stable@vger.kernel.org Reviewed-by: Oliver Upton <oupton@kernel.org> Link: https://patch.msgid.link/20251030122707.2033690-2-maz@kernel.org Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 103e17a commit 3f9eacf

File tree

1 file changed

+31
-28
lines changed

1 file changed

+31
-28
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2595,19 +2595,23 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
25952595
.val = 0, \
25962596
}
25972597

2598-
/* sys_reg_desc initialiser for known cpufeature ID registers */
2599-
#define AA32_ID_SANITISED(name) { \
2600-
ID_DESC(name), \
2601-
.visibility = aa32_id_visibility, \
2602-
.val = 0, \
2603-
}
2604-
26052598
/* sys_reg_desc initialiser for writable ID registers */
26062599
#define ID_WRITABLE(name, mask) { \
26072600
ID_DESC(name), \
26082601
.val = mask, \
26092602
}
26102603

2604+
/*
2605+
* 32bit ID regs are fully writable when the guest is 32bit
2606+
* capable. Nothing in the KVM code should rely on 32bit features
2607+
* anyway, only 64bit, so let the VMM do its worse.
2608+
*/
2609+
#define AA32_ID_WRITABLE(name) { \
2610+
ID_DESC(name), \
2611+
.visibility = aa32_id_visibility, \
2612+
.val = GENMASK(31, 0), \
2613+
}
2614+
26112615
/* sys_reg_desc initialiser for cpufeature ID registers that need filtering */
26122616
#define ID_FILTERED(sysreg, name, mask) { \
26132617
ID_DESC(sysreg), \
@@ -3128,40 +3132,39 @@ static const struct sys_reg_desc sys_reg_descs[] = {
31283132

31293133
/* AArch64 mappings of the AArch32 ID registers */
31303134
/* CRm=1 */
3131-
AA32_ID_SANITISED(ID_PFR0_EL1),
3132-
AA32_ID_SANITISED(ID_PFR1_EL1),
3135+
AA32_ID_WRITABLE(ID_PFR0_EL1),
3136+
AA32_ID_WRITABLE(ID_PFR1_EL1),
31333137
{ SYS_DESC(SYS_ID_DFR0_EL1),
31343138
.access = access_id_reg,
31353139
.get_user = get_id_reg,
31363140
.set_user = set_id_dfr0_el1,
31373141
.visibility = aa32_id_visibility,
31383142
.reset = read_sanitised_id_dfr0_el1,
3139-
.val = ID_DFR0_EL1_PerfMon_MASK |
3140-
ID_DFR0_EL1_CopDbg_MASK, },
3143+
.val = GENMASK(31, 0) },
31413144
ID_HIDDEN(ID_AFR0_EL1),
3142-
AA32_ID_SANITISED(ID_MMFR0_EL1),
3143-
AA32_ID_SANITISED(ID_MMFR1_EL1),
3144-
AA32_ID_SANITISED(ID_MMFR2_EL1),
3145-
AA32_ID_SANITISED(ID_MMFR3_EL1),
3145+
AA32_ID_WRITABLE(ID_MMFR0_EL1),
3146+
AA32_ID_WRITABLE(ID_MMFR1_EL1),
3147+
AA32_ID_WRITABLE(ID_MMFR2_EL1),
3148+
AA32_ID_WRITABLE(ID_MMFR3_EL1),
31463149

31473150
/* CRm=2 */
3148-
AA32_ID_SANITISED(ID_ISAR0_EL1),
3149-
AA32_ID_SANITISED(ID_ISAR1_EL1),
3150-
AA32_ID_SANITISED(ID_ISAR2_EL1),
3151-
AA32_ID_SANITISED(ID_ISAR3_EL1),
3152-
AA32_ID_SANITISED(ID_ISAR4_EL1),
3153-
AA32_ID_SANITISED(ID_ISAR5_EL1),
3154-
AA32_ID_SANITISED(ID_MMFR4_EL1),
3155-
AA32_ID_SANITISED(ID_ISAR6_EL1),
3151+
AA32_ID_WRITABLE(ID_ISAR0_EL1),
3152+
AA32_ID_WRITABLE(ID_ISAR1_EL1),
3153+
AA32_ID_WRITABLE(ID_ISAR2_EL1),
3154+
AA32_ID_WRITABLE(ID_ISAR3_EL1),
3155+
AA32_ID_WRITABLE(ID_ISAR4_EL1),
3156+
AA32_ID_WRITABLE(ID_ISAR5_EL1),
3157+
AA32_ID_WRITABLE(ID_MMFR4_EL1),
3158+
AA32_ID_WRITABLE(ID_ISAR6_EL1),
31563159

31573160
/* CRm=3 */
3158-
AA32_ID_SANITISED(MVFR0_EL1),
3159-
AA32_ID_SANITISED(MVFR1_EL1),
3160-
AA32_ID_SANITISED(MVFR2_EL1),
3161+
AA32_ID_WRITABLE(MVFR0_EL1),
3162+
AA32_ID_WRITABLE(MVFR1_EL1),
3163+
AA32_ID_WRITABLE(MVFR2_EL1),
31613164
ID_UNALLOCATED(3,3),
3162-
AA32_ID_SANITISED(ID_PFR2_EL1),
3165+
AA32_ID_WRITABLE(ID_PFR2_EL1),
31633166
ID_HIDDEN(ID_DFR1_EL1),
3164-
AA32_ID_SANITISED(ID_MMFR5_EL1),
3167+
AA32_ID_WRITABLE(ID_MMFR5_EL1),
31653168
ID_UNALLOCATED(3,7),
31663169

31673170
/* AArch64 ID registers */

0 commit comments

Comments
 (0)