KVM: arm64: Get rid of REG_HIDDEN_USER
Marc Zyngier
maintainercover KVM: arm64: Get rid of REG_HIDDEN_USER
REG_HIDDEN_USER was introduced as a way to deal with the ARMv8.3 flavour of FEAT_NV, where most EL12 sysreg accesses would trap and yet be mapped to a EL1 register (KVM doing in SW what FEAT_NV2 does in HW). This handling imposed that the EL12 register shouldn't be visible to userspace, hence the special REG_HIDDEN_USER visibility.
Since 4d4f52052ba8 ("KVM: arm64: nv: Drop EL12 register traps that are redirected to VNCR") and the admission that KVM would never be supporting the original FEAT_NV, REG_HIDDEN_USER only had a few users, all of which could either be replaced by a more ad-hoc mechanism, or removed altogether.
This series goes ahead and cleans it up for good, removing a tiny bit of unnecessary complexity.
Marc Zyngier (3):
KVM: arm64: Simplify handling of CNTKCTL_EL12
KVM: arm64: Simplify visibility handling of AArch32 SPSR_*
KVM: arm64: Get rid of REG_HIDDEN_USER visibility qualifier
arch/arm64/kvm/sys_regs.c | 52 +++++++++++++++------------------------ arch/arm64/kvm/sys_regs.h | 14 ++--------- 2 files changed, 22 insertions(+), 44 deletions(-)
Signature · 1 line
2.39.2
Marc Zyngier
maintainerPATCH 1/3 KVM: arm64: Simplify handling of CNTKCTL_EL12
We go trough a great deal of effort to map CNTKCTL_EL12 to CNTKCTL_EL1 while hidding this mapping from userspace via a special visibility helper.
However, it would be far simpler to just provide an accessor doing the mapping job, removing the need for a visibility helper.
With that done, we can also remove the EL12_REG() macro which serves no purpose.
--- arch/arm64/kvm/sys_regs.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
arch/arm64/kvm/sys_regs.c +13 -10
@@ -2105,15 +2105,6 @@ static unsigned int hidden_user_visibility(const struct kvm_vcpu *vcpu,return REG_HIDDEN_USER ; } -#define EL12_REG (name, acc, rst, v) { \ - SYS_DESC(SYS_##name##_EL12), \ - .access = acc, \ - .reset = rst, \ - .reg = name##_EL1, \ - .val = v, \ - .visibility = hidden_user_visibility, \ -} -/* * Since reset() callback and field val are not used for idregs, they will be * used for specific purposes for idregs.
@@ -2221,6 +2212,18 @@ static bool access_spsr(struct kvm_vcpu *vcpu,return true; } +static bool access_cntkctl_el12 (struct kvm_vcpu *vcpu, +struct sys_reg_params *p, +const struct sys_reg_desc *r) +{ +if (p->is_write) +__vcpu_sys_reg (vcpu,CNTKCTL_EL1 ) = p->regval; +else + p->regval =__vcpu_sys_reg (vcpu,CNTKCTL_EL1 ); + +return true; +} +static u64 reset_hcr (struct kvm_vcpu *vcpu,const struct sys_reg_desc *r) {u64 val = r->val;
@@ -2825,7 +2828,7 @@ static const struct sys_reg_desc sys_reg_descs[] = {EL2_REG_VNCR (CNTVOFF_EL2 , reset_val,0 ),EL2_REG (CNTHCTL_EL2 , access_rw, reset_val,0 ), -EL12_REG (CNTKCTL , access_rw, reset_val,0 ), + { SYS_DESC(SYS_CNTKCTL_EL12), access_cntkctl_el12 }, EL2_REG(SP_EL2, NULL, reset_unknown, 0), };
Signature · 1 line
2.39.2
Marc Zyngier
maintainerPATCH 2/3 KVM: arm64: Simplify visibility handling of AArch32 SPSR_*
In reply to Marc ZyngierSince SPSR_* are not associated with any register in the sysreg array, nor do they have .get_user()/.set_user() helpers, they are invisible to userspace with that encoding.
Therefore hidden_user_visibility() serves no purpose here, and can be safely removed.
--- arch/arm64/kvm/sys_regs.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-)
arch/arm64/kvm/sys_regs.c +4 -8
@@ -2795,14 +2795,10 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_SP_EL1), access_sp_el1},/* AArch32 SPSR_* are RES0 if trapped from a NV guest */ - { SYS_DESC(SYS_SPSR_irq), .access = trap_raz_wi, - .visibility = hidden_user_visibility }, - { SYS_DESC(SYS_SPSR_abt), .access = trap_raz_wi, - .visibility = hidden_user_visibility }, - { SYS_DESC(SYS_SPSR_und), .access = trap_raz_wi, - .visibility = hidden_user_visibility }, - { SYS_DESC(SYS_SPSR_fiq), .access = trap_raz_wi, - .visibility = hidden_user_visibility }, + { SYS_DESC(SYS_SPSR_irq), .access = trap_raz_wi }, + { SYS_DESC(SYS_SPSR_abt), .access = trap_raz_wi }, + { SYS_DESC(SYS_SPSR_und), .access = trap_raz_wi }, + { SYS_DESC(SYS_SPSR_fiq), .access = trap_raz_wi }, { SYS_DESC(SYS_IFSR32_EL2), undef_access, reset_unknown, IFSR32_EL2 }, EL2_REG(AFSR0_EL2, access_rw, reset_val, 0),
Signature · 1 line
2.39.2
Marc Zyngier
maintainerPATCH 3/3 KVM: arm64: Get rid of REG_HIDDEN_USER visibility qualifier
In reply to Marc ZyngierNow that REG_HIDDEN_USER has no direct user anymore, remove it entirely and update all users of sysreg_hidden_user() to call sysreg_hidden() instead.
--- arch/arm64/kvm/sys_regs.c | 17 +++-------------- arch/arm64/kvm/sys_regs.h | 14 ++------------ 2 files changed, 5 insertions(+), 26 deletions(-)
arch/arm64/kvm/sys_regs.c +3 -14
@@ -2094,17 +2094,6 @@ static bool bad_redir_trap(struct kvm_vcpu *vcpu,#define EL2_REG_VNCR (name, rst, v) EL2_REG(name, bad_vncr_trap, rst, v)#define EL2_REG_REDIR (name, rst, v) EL2_REG(name, bad_redir_trap, rst, v) -/* -* EL{0,1}2 registers are the EL2 view on an EL0 or EL1 register when -* HCR_EL2.E2H==1, and only in the sysreg table for convenience of -* handling traps. Given that, they are always hidden from userspace. -*/ -static unsigned int hidden_user_visibility (const struct kvm_vcpu *vcpu, -const struct sys_reg_desc *rd) -{ -return REG_HIDDEN_USER ; -} -/* * Since reset() callback and field val are not used for idregs, they will be * used for specific purposes for idregs.
@@ -4364,7 +4353,7 @@ int kvm_sys_reg_get_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,int ret; r =id_to_sys_reg_desc (vcpu, reg->id, table, num); -if (!r ||sysreg_hidden_user (vcpu, r)) +if (!r ||sysreg_hidden (vcpu, r))return -ENOENT ;if (r->get_user) {
@@ -4408,7 +4397,7 @@ int kvm_sys_reg_set_user(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg,return -EFAULT ; r =id_to_sys_reg_desc (vcpu, reg->id, table, num); -if (!r ||sysreg_hidden_user (vcpu, r)) +if (!r ||sysreg_hidden (vcpu, r))return -ENOENT ;if (sysreg_user_write_ignore (vcpu, r))
@@ -4494,7 +4483,7 @@ static int walk_one_sys_reg(const struct kvm_vcpu *vcpu,if (!(rd->reg || rd->get_user))return 0 ; -if (sysreg_hidden_user (vcpu, rd)) +if (sysreg_hidden (vcpu, rd))return 0 ;if (!copy_reg_to_user (rd, uind))
arch/arm64/kvm/sys_regs.h +2 -12
@@ -95,9 +95,8 @@ struct sys_reg_desc { };#define REG_HIDDEN (1 << 0)/* hidden from userspace and guest */ -#define REG_HIDDEN_USER (1 << 1)/* hidden from userspace only */ -#define REG_RAZ (1 << 2)/* RAZ from userspace and guest */ -#define REG_USER_WI (1 << 3)/* WI from userspace only */ +#define REG_RAZ (1 << 1)/* RAZ from userspace and guest */ +#define REG_USER_WI (1 << 2)/* WI from userspace only */ static __printf(2, 3) inline void print_sys_reg_msg(const struct sys_reg_params *p,
@@ -165,15 +164,6 @@ static inline bool sysreg_hidden(const struct kvm_vcpu *vcpu,return sysreg_visibility (vcpu, r) ®_HIDDEN ; } -static inline bool sysreg_hidden_user (const struct kvm_vcpu *vcpu, -const struct sys_reg_desc *r) -{ -if (likely (!r->visibility)) -return false; - -return r->visibility (vcpu, r) & (REG_HIDDEN |REG_HIDDEN_USER ); -} -static inline bool sysreg_visible_as_raz (const struct kvm_vcpu *vcpu,const struct sys_reg_desc *r) {
Signature · 1 line
2.39.2
Quoted 6 lines · Marc Zyngier
REG_HIDDEN_USERwas introduced as a way to deal with the ARMv8.3 flavour ofFEAT_NV, where most EL12 sysreg accesses would trap and yet be mapped to a EL1 register (KVM doing in SW whatFEAT_NV2does in HW). This handling imposed that the EL12 register shouldn't be visible to userspace, hence the specialREG_HIDDEN_USERvisibility.
Quoted 7 lines
Since
4d4f52052ba8("KVM: arm64: nv: Drop EL12 register traps that are redirected to VNCR") and the admission that KVM would never be supporting the originalFEAT_NV,REG_HIDDEN_USERonly had a few users, all of which could either be replaced by a more ad-hoc mechanism, or removed altogether.This series goes ahead and cleans it up for good, removing a tiny bit of unnecessary complexity.
Yeah, let's toss it.
Signature · 2 lines
Thanks, Oliver
Quoted 6 lines · Marc Zyngier
REG_HIDDEN_USERwas introduced as a way to deal with the ARMv8.3 flavour ofFEAT_NV, where most EL12 sysreg accesses would trap and yet be mapped to a EL1 register (KVM doing in SW whatFEAT_NV2does in HW). This handling imposed that the EL12 register shouldn't be visible to userspace, hence the specialREG_HIDDEN_USERvisibility.
Quoted 6 lines
Since
4d4f52052ba8("KVM: arm64: nv: Drop EL12 register traps that are redirected to VNCR") and the admission that KVM would never be supporting the originalFEAT_NV,REG_HIDDEN_USERonly had a few users, all of which could either be replaced by a more ad-hoc mechanism, or removed altogether.[...]
Applied to next, thanks!
[1/3] KVM: arm64: Simplify handling of CNTKCTL_EL12
commit: 989fce63b2cb5061701c9fa04711d992dfaff5c6
[2/3] KVM: arm64: Simplify visibility handling of AArch32 SPSR_*
commit: 84ed45456cee7e77effea8407f4f32b262f2e2ea
[3/3] KVM: arm64: Get rid of REG_HIDDEN_USER visibility qualifier
commit: 0746096faca01823021f662282e1f067a69b965bCheers,
M.
Signature · 1 line
Without deviation from the norm, progress is not possible.