Skip to content

Commit 7da540e

Browse files
James Morseoupton
authored andcommitted
KVM: arm64: Add a macro for creating filtered sys_reg_descs entries
The sys_reg_descs array holds function pointers and reset value for managing the user-space and guest view of system registers. These are mostly created by a set of macro's as only some combinations of behaviour are needed. If a register needs special treatment, its sys_reg_descs entry is open-coded. This is true of some id registers where the value provided by user-space is validated by some helpers. Before adding another one of these, add a helper that covers the existing special cases. 'ID_FILTERED' expects helpers to set the user-space value, and retrieve the modified reset value. Like ID_WRITABLE() this uses id_visibility(), which should have no functional change for the registers converted to use ID_FILTERED(). read_sanitised_id_aa64dfr0_el1() and read_sanitised_id_aa64pfr0_el1() have been refactored to be called from kvm_read_sanitised_id_reg(), to try be consistent with ID_WRITABLE(). Signed-off-by: James Morse <james.morse@arm.com> Signed-off-by: Joey Gouly <joey.gouly@arm.com> Reviewed-by: Gavin Shan <gshan@redhat.com> Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20241030160317.2528209-6-joey.gouly@arm.com Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent 31ff96c commit 7da540e

File tree

1 file changed

+38
-28
lines changed

1 file changed

+38
-28
lines changed

arch/arm64/kvm/sys_regs.c

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,6 +1509,9 @@ static u8 pmuver_to_perfmon(u8 pmuver)
15091509
}
15101510
}
15111511

1512+
static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
1513+
static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val);
1514+
15121515
/* Read a sanitised cpufeature ID register by sys_reg_desc */
15131516
static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
15141517
const struct sys_reg_desc *r)
@@ -1522,6 +1525,12 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu,
15221525
val = read_sanitised_ftr_reg(id);
15231526

15241527
switch (id) {
1528+
case SYS_ID_AA64DFR0_EL1:
1529+
val = sanitise_id_aa64dfr0_el1(vcpu, val);
1530+
break;
1531+
case SYS_ID_AA64PFR0_EL1:
1532+
val = sanitise_id_aa64pfr0_el1(vcpu, val);
1533+
break;
15251534
case SYS_ID_AA64PFR1_EL1:
15261535
if (!kvm_has_mte(vcpu->kvm))
15271536
val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE);
@@ -1692,11 +1701,8 @@ static unsigned int fp8_visibility(const struct kvm_vcpu *vcpu,
16921701
return REG_HIDDEN;
16931702
}
16941703

1695-
static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1696-
const struct sys_reg_desc *rd)
1704+
static u64 sanitise_id_aa64pfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
16971705
{
1698-
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1);
1699-
17001706
if (!vcpu_has_sve(vcpu))
17011707
val &= ~ID_AA64PFR0_EL1_SVE_MASK;
17021708

@@ -1737,11 +1743,8 @@ static u64 read_sanitised_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
17371743
(val); \
17381744
})
17391745

1740-
static u64 read_sanitised_id_aa64dfr0_el1(struct kvm_vcpu *vcpu,
1741-
const struct sys_reg_desc *rd)
1746+
static u64 sanitise_id_aa64dfr0_el1(const struct kvm_vcpu *vcpu, u64 val)
17421747
{
1743-
u64 val = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
1744-
17451748
val = ID_REG_LIMIT_FIELD_ENUM(val, ID_AA64DFR0_EL1, DebugVer, V8P8);
17461749

17471750
/*
@@ -1834,6 +1837,12 @@ static int set_id_dfr0_el1(struct kvm_vcpu *vcpu,
18341837
return set_id_reg(vcpu, rd, val);
18351838
}
18361839

1840+
static int set_id_aa64pfr0_el1(struct kvm_vcpu *vcpu,
1841+
const struct sys_reg_desc *rd, u64 val)
1842+
{
1843+
return set_id_reg(vcpu, rd, val);
1844+
}
1845+
18371846
/*
18381847
* cpufeature ID register user accessors
18391848
*
@@ -2150,6 +2159,15 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,
21502159
.val = mask, \
21512160
}
21522161

2162+
/* sys_reg_desc initialiser for cpufeature ID registers that need filtering */
2163+
#define ID_FILTERED(sysreg, name, mask) { \
2164+
ID_DESC(sysreg), \
2165+
.set_user = set_##name, \
2166+
.visibility = id_visibility, \
2167+
.reset = kvm_read_sanitised_id_reg, \
2168+
.val = (mask), \
2169+
}
2170+
21532171
/*
21542172
* sys_reg_desc initialiser for architecturally unallocated cpufeature ID
21552173
* register with encoding Op0=3, Op1=0, CRn=0, CRm=crm, Op2=op2
@@ -2374,17 +2392,13 @@ static const struct sys_reg_desc sys_reg_descs[] = {
23742392

23752393
/* AArch64 ID registers */
23762394
/* CRm=4 */
2377-
{ SYS_DESC(SYS_ID_AA64PFR0_EL1),
2378-
.access = access_id_reg,
2379-
.get_user = get_id_reg,
2380-
.set_user = set_id_reg,
2381-
.reset = read_sanitised_id_aa64pfr0_el1,
2382-
.val = ~(ID_AA64PFR0_EL1_AMU |
2383-
ID_AA64PFR0_EL1_MPAM |
2384-
ID_AA64PFR0_EL1_SVE |
2385-
ID_AA64PFR0_EL1_RAS |
2386-
ID_AA64PFR0_EL1_AdvSIMD |
2387-
ID_AA64PFR0_EL1_FP), },
2395+
ID_FILTERED(ID_AA64PFR0_EL1, id_aa64pfr0_el1,
2396+
~(ID_AA64PFR0_EL1_AMU |
2397+
ID_AA64PFR0_EL1_MPAM |
2398+
ID_AA64PFR0_EL1_SVE |
2399+
ID_AA64PFR0_EL1_RAS |
2400+
ID_AA64PFR0_EL1_AdvSIMD |
2401+
ID_AA64PFR0_EL1_FP)),
23882402
ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_PFAR |
23892403
ID_AA64PFR1_EL1_DF2 |
23902404
ID_AA64PFR1_EL1_MTEX |
@@ -2406,11 +2420,6 @@ static const struct sys_reg_desc sys_reg_descs[] = {
24062420
ID_WRITABLE(ID_AA64FPFR0_EL1, ~ID_AA64FPFR0_EL1_RES0),
24072421

24082422
/* CRm=5 */
2409-
{ SYS_DESC(SYS_ID_AA64DFR0_EL1),
2410-
.access = access_id_reg,
2411-
.get_user = get_id_reg,
2412-
.set_user = set_id_aa64dfr0_el1,
2413-
.reset = read_sanitised_id_aa64dfr0_el1,
24142423
/*
24152424
* Prior to FEAT_Debugv8.9, the architecture defines context-aware
24162425
* breakpoints (CTX_CMPs) as the highest numbered breakpoints (BRPs).
@@ -2423,10 +2432,11 @@ static const struct sys_reg_desc sys_reg_descs[] = {
24232432
* See DDI0487K.a, section D2.8.3 Breakpoint types and linking
24242433
* of breakpoints for more details.
24252434
*/
2426-
.val = ID_AA64DFR0_EL1_DoubleLock_MASK |
2427-
ID_AA64DFR0_EL1_WRPs_MASK |
2428-
ID_AA64DFR0_EL1_PMUVer_MASK |
2429-
ID_AA64DFR0_EL1_DebugVer_MASK, },
2435+
ID_FILTERED(ID_AA64DFR0_EL1, id_aa64dfr0_el1,
2436+
ID_AA64DFR0_EL1_DoubleLock_MASK |
2437+
ID_AA64DFR0_EL1_WRPs_MASK |
2438+
ID_AA64DFR0_EL1_PMUVer_MASK |
2439+
ID_AA64DFR0_EL1_DebugVer_MASK),
24302440
ID_SANITISED(ID_AA64DFR1_EL1),
24312441
ID_UNALLOCATED(5,2),
24322442
ID_UNALLOCATED(5,3),

0 commit comments

Comments
 (0)