Commit 0ccd901d authored by Fuad Tabba's avatar Fuad Tabba Committed by Marc Zyngier
Browse files

KVM: arm64: Macros for setting/clearing FGT bits



There's a lot of boilerplate code for setting and clearing FGT
bits when activating guest traps. Refactor it into macros. These
macros will also be used in future patch series.

No functional change intended.

Signed-off-by: default avatarFuad Tabba <tabba@google.com>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20231214100158.2305400-15-tabba@google.com
parent 5f6bd3f3
Loading
Loading
Loading
Loading
+27 −42
Original line number Diff line number Diff line
@@ -79,6 +79,27 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
		clr |= ~hfg & __ ## reg ## _nMASK; 			\
	} while(0)

#define update_fgt_traps_cs(vcpu, reg, clr, set)			\
	do {								\
		struct kvm_cpu_context *hctxt =				\
			&this_cpu_ptr(&kvm_host_data)->host_ctxt;	\
		u64 c = 0, s = 0;					\
									\
		ctxt_sys_reg(hctxt, reg) = read_sysreg_s(SYS_ ## reg);	\
		compute_clr_set(vcpu, reg, c, s);			\
		s |= set;						\
		c |= clr;						\
		if (c || s) {						\
			u64 val = __ ## reg ## _nMASK;			\
			val |= s;					\
			val &= ~c;					\
			write_sysreg_s(val, SYS_ ## reg);		\
		}							\
	} while(0)

#define update_fgt_traps(vcpu, reg)		\
	update_fgt_traps_cs(vcpu, reg, 0, 0)

/*
 * Validate the fine grain trap masks.
 * Check that the masks do not overlap and that all bits are accounted for.
@@ -154,48 +175,12 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
	if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
		return;

	ctxt_sys_reg(hctxt, HFGITR_EL2) = read_sysreg_s(SYS_HFGITR_EL2);

	r_set = r_clr = 0;
	compute_clr_set(vcpu, HFGITR_EL2, r_clr, r_set);
	r_val = __HFGITR_EL2_nMASK;
	r_val |= r_set;
	r_val &= ~r_clr;

	write_sysreg_s(r_val, SYS_HFGITR_EL2);

	ctxt_sys_reg(hctxt, HDFGRTR_EL2) = read_sysreg_s(SYS_HDFGRTR_EL2);
	ctxt_sys_reg(hctxt, HDFGWTR_EL2) = read_sysreg_s(SYS_HDFGWTR_EL2);

	r_clr = r_set = w_clr = w_set = 0;

	compute_clr_set(vcpu, HDFGRTR_EL2, r_clr, r_set);
	compute_clr_set(vcpu, HDFGWTR_EL2, w_clr, w_set);

	r_val = __HDFGRTR_EL2_nMASK;
	r_val |= r_set;
	r_val &= ~r_clr;

	w_val = __HDFGWTR_EL2_nMASK;
	w_val |= w_set;
	w_val &= ~w_clr;

	write_sysreg_s(r_val, SYS_HDFGRTR_EL2);
	write_sysreg_s(w_val, SYS_HDFGWTR_EL2);

       if (!cpu_has_amu())
               return;

	ctxt_sys_reg(hctxt, HAFGRTR_EL2) = read_sysreg_s(SYS_HAFGRTR_EL2);

	r_clr = r_set = 0;
	compute_clr_set(vcpu, HAFGRTR_EL2, r_clr, r_set);

	r_val = __HAFGRTR_EL2_nMASK;
	r_val |= r_set;
	r_val &= ~r_clr;
	update_fgt_traps(vcpu, HFGITR_EL2);
	update_fgt_traps(vcpu, HDFGRTR_EL2);
	update_fgt_traps(vcpu, HDFGWTR_EL2);

	write_sysreg_s(r_val, SYS_HAFGRTR_EL2);
	if (cpu_has_amu())
		update_fgt_traps(vcpu, HAFGRTR_EL2);
}

static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
@@ -215,7 +200,7 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
	write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);

	if (vcpu_has_amu())
	if (cpu_has_amu())
		write_sysreg_s(ctxt_sys_reg(hctxt, HAFGRTR_EL2), SYS_HAFGRTR_EL2);
}