[PATCH v3 16/42] KVM: arm64: Simplify handling of negative FGT bits
Joey Gouly
joey.gouly at arm.com
Thu May 1 03:43:36 PDT 2025
On Sat, Apr 26, 2025 at 01:28:10PM +0100, Marc Zyngier wrote:
> check_fgt_bit() and triage_sysreg_trap() implement the same thing
> twice for no good reason. We have to lookup the FGT register twice,
> as we don't communucate it. Similarly, we extract the register value
> at the wrong spot.
>
> Reorganise the code in a more logical way so that things are done
> at the correct location, removing a lot of duplication.
Reviewed-by: Joey Gouly <joey.gouly at arm.com>
>
> Signed-off-by: Marc Zyngier <maz at kernel.org>
> ---
> arch/arm64/kvm/emulate-nested.c | 49 ++++++++-------------------------
> 1 file changed, 12 insertions(+), 37 deletions(-)
>
> diff --git a/arch/arm64/kvm/emulate-nested.c b/arch/arm64/kvm/emulate-nested.c
> index 1bcbddc88a9b7..52a2d63a667c9 100644
> --- a/arch/arm64/kvm/emulate-nested.c
> +++ b/arch/arm64/kvm/emulate-nested.c
> @@ -2215,11 +2215,11 @@ static u64 kvm_get_sysreg_res0(struct kvm *kvm, enum vcpu_sysreg sr)
> return masks->mask[sr - __VNCR_START__].res0;
> }
>
> -static bool check_fgt_bit(struct kvm_vcpu *vcpu, bool is_read,
> - u64 val, const union trap_config tc)
> +static bool check_fgt_bit(struct kvm_vcpu *vcpu, enum vcpu_sysreg sr,
> + const union trap_config tc)
> {
> struct kvm *kvm = vcpu->kvm;
> - enum vcpu_sysreg sr;
> + u64 val;
>
> /*
> * KVM doesn't know about any FGTs that apply to the host, and hopefully
> @@ -2228,6 +2228,8 @@ static bool check_fgt_bit(struct kvm_vcpu *vcpu, bool is_read,
> if (is_hyp_ctxt(vcpu))
> return false;
>
> + val = __vcpu_sys_reg(vcpu, sr);
> +
> if (tc.pol)
> return (val & BIT(tc.bit));
>
> @@ -2242,38 +2244,17 @@ static bool check_fgt_bit(struct kvm_vcpu *vcpu, bool is_read,
> if (val & BIT(tc.bit))
> return false;
>
> - switch ((enum fgt_group_id)tc.fgt) {
> - case HFGRTR_GROUP:
> - sr = is_read ? HFGRTR_EL2 : HFGWTR_EL2;
> - break;
> -
> - case HDFGRTR_GROUP:
> - sr = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
> - break;
> -
> - case HAFGRTR_GROUP:
> - sr = HAFGRTR_EL2;
> - break;
> -
> - case HFGITR_GROUP:
> - sr = HFGITR_EL2;
> - break;
> -
> - default:
> - WARN_ONCE(1, "Unhandled FGT group");
> - return false;
> - }
> -
> return !(kvm_get_sysreg_res0(kvm, sr) & BIT(tc.bit));
> }
>
> bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
> {
> + enum vcpu_sysreg fgtreg;
> union trap_config tc;
> enum trap_behaviour b;
> bool is_read;
> u32 sysreg;
> - u64 esr, val;
> + u64 esr;
>
> esr = kvm_vcpu_get_esr(vcpu);
> sysreg = esr_sys64_to_sysreg(esr);
> @@ -2320,25 +2301,19 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
> break;
>
> case HFGRTR_GROUP:
> - if (is_read)
> - val = __vcpu_sys_reg(vcpu, HFGRTR_EL2);
> - else
> - val = __vcpu_sys_reg(vcpu, HFGWTR_EL2);
> + fgtreg = is_read ? HFGRTR_EL2 : HFGWTR_EL2;
> break;
>
> case HDFGRTR_GROUP:
> - if (is_read)
> - val = __vcpu_sys_reg(vcpu, HDFGRTR_EL2);
> - else
> - val = __vcpu_sys_reg(vcpu, HDFGWTR_EL2);
> + fgtreg = is_read ? HDFGRTR_EL2 : HDFGWTR_EL2;
> break;
>
> case HAFGRTR_GROUP:
> - val = __vcpu_sys_reg(vcpu, HAFGRTR_EL2);
> + fgtreg = HAFGRTR_EL2;
> break;
>
> case HFGITR_GROUP:
> - val = __vcpu_sys_reg(vcpu, HFGITR_EL2);
> + fgtreg = HFGITR_EL2;
> switch (tc.fgf) {
> u64 tmp;
>
> @@ -2359,7 +2334,7 @@ bool triage_sysreg_trap(struct kvm_vcpu *vcpu, int *sr_index)
> goto local;
> }
>
> - if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu, is_read, val, tc))
> + if (tc.fgt != __NO_FGT_GROUP__ && check_fgt_bit(vcpu, fgtreg, tc))
> goto inject;
>
> b = compute_trap_behaviour(vcpu, tc);
> --
> 2.39.2
>
More information about the linux-arm-kernel
mailing list