Skip to content

Commit 5aea409

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: nv: Allow userspace to de-feature stage-2 TGRANs
KVM advertises the stage-2 TGRAN fields as writable to userspace but prevents any modification for NV-enabled VMs. Update the special-cased sanitization to permit de-featuring a particular TGRAN without allowing the legacy value which refers to the stage-1 field for support. Reported-by: Itaru Kitayama <itaru.kitayama@linux.dev> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent ff37a41 commit 5aea409

1 file changed

Lines changed: 18 additions & 5 deletions

File tree

arch/arm64/kvm/sys_regs.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,16 +2148,29 @@ static int set_id_aa64pfr1_el1(struct kvm_vcpu *vcpu,
21482148
return set_id_reg(vcpu, rd, user_val);
21492149
}
21502150

2151+
/*
2152+
* Allow userspace to de-feature a stage-2 translation granule but prevent it
2153+
* from claiming the impossible.
2154+
*/
2155+
#define tgran2_val_allowed(tg, safe, user) \
2156+
({ \
2157+
u8 __s = SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, safe); \
2158+
u8 __u = SYS_FIELD_GET(ID_AA64MMFR0_EL1, tg, user); \
2159+
\
2160+
__s == __u || __u == ID_AA64MMFR0_EL1_##tg##_NI; \
2161+
})
2162+
21512163
static int set_id_aa64mmfr0_el1(struct kvm_vcpu *vcpu,
21522164
const struct sys_reg_desc *rd, u64 user_val)
21532165
{
21542166
u64 sanitized_val = kvm_read_sanitised_id_reg(vcpu, rd);
2155-
u64 tgran2_mask = ID_AA64MMFR0_EL1_TGRAN4_2_MASK |
2156-
ID_AA64MMFR0_EL1_TGRAN16_2_MASK |
2157-
ID_AA64MMFR0_EL1_TGRAN64_2_MASK;
21582167

2159-
if (vcpu_has_nv(vcpu) &&
2160-
((sanitized_val & tgran2_mask) != (user_val & tgran2_mask)))
2168+
if (!vcpu_has_nv(vcpu))
2169+
return set_id_reg(vcpu, rd, user_val);
2170+
2171+
if (!tgran2_val_allowed(TGRAN4_2, sanitized_val, user_val) ||
2172+
!tgran2_val_allowed(TGRAN16_2, sanitized_val, user_val) ||
2173+
!tgran2_val_allowed(TGRAN64_2, sanitized_val, user_val))
21612174
return -EINVAL;
21622175

21632176
return set_id_reg(vcpu, rd, user_val);

0 commit comments

Comments
 (0)