Skip to content

Commit d4d2dac

Browse files
author
Marc Zyngier
committed
KVM: arm64: nv: Add switching support for HFGxTR/HDFGxTR
Now that we can evaluate the FGT registers, allow them to be merged with the hypervisor's own configuration (in the case of HFG{RW}TR_EL2) or simply set for HFGITR_EL2, HDGFRTR_EL2 and HDFGWTR_EL2. Reviewed-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Jing Zhang <jingzhangos@google.com> Link: https://lore.kernel.org/r/20230815183903.2735724-26-maz@kernel.org
1 parent ea3b27d commit d4d2dac

File tree

1 file changed

+48
-0
lines changed

1 file changed

+48
-0
lines changed

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,13 @@ static inline void __activate_traps_fpsimd32(struct kvm_vcpu *vcpu)
7070
}
7171
}
7272

73+
#define compute_clr_set(vcpu, reg, clr, set) \
74+
do { \
75+
u64 hfg; \
76+
hfg = __vcpu_sys_reg(vcpu, reg) & ~__ ## reg ## _RES0; \
77+
set |= hfg & __ ## reg ## _MASK; \
78+
clr |= ~hfg & __ ## reg ## _nMASK; \
79+
} while(0)
7380

7481

7582
static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
@@ -97,6 +104,10 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
97104
if (cpus_have_final_cap(ARM64_WORKAROUND_AMPERE_AC03_CPU_38))
98105
w_set |= HFGxTR_EL2_TCR_EL1_MASK;
99106

107+
if (vcpu_has_nv(vcpu) && !is_hyp_ctxt(vcpu)) {
108+
compute_clr_set(vcpu, HFGRTR_EL2, r_clr, r_set);
109+
compute_clr_set(vcpu, HFGWTR_EL2, w_clr, w_set);
110+
}
100111

101112
/* The default is not to trap anything but ACCDATA_EL1 */
102113
r_val = __HFGRTR_EL2_nMASK & ~HFGxTR_EL2_nACCDATA_EL1;
@@ -109,6 +120,38 @@ static inline void __activate_traps_hfgxtr(struct kvm_vcpu *vcpu)
109120

110121
write_sysreg_s(r_val, SYS_HFGRTR_EL2);
111122
write_sysreg_s(w_val, SYS_HFGWTR_EL2);
123+
124+
if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
125+
return;
126+
127+
ctxt_sys_reg(hctxt, HFGITR_EL2) = read_sysreg_s(SYS_HFGITR_EL2);
128+
129+
r_set = r_clr = 0;
130+
compute_clr_set(vcpu, HFGITR_EL2, r_clr, r_set);
131+
r_val = __HFGITR_EL2_nMASK;
132+
r_val |= r_set;
133+
r_val &= ~r_clr;
134+
135+
write_sysreg_s(r_val, SYS_HFGITR_EL2);
136+
137+
ctxt_sys_reg(hctxt, HDFGRTR_EL2) = read_sysreg_s(SYS_HDFGRTR_EL2);
138+
ctxt_sys_reg(hctxt, HDFGWTR_EL2) = read_sysreg_s(SYS_HDFGWTR_EL2);
139+
140+
r_clr = r_set = w_clr = w_set = 0;
141+
142+
compute_clr_set(vcpu, HDFGRTR_EL2, r_clr, r_set);
143+
compute_clr_set(vcpu, HDFGWTR_EL2, w_clr, w_set);
144+
145+
r_val = __HDFGRTR_EL2_nMASK;
146+
r_val |= r_set;
147+
r_val &= ~r_clr;
148+
149+
w_val = __HDFGWTR_EL2_nMASK;
150+
w_val |= w_set;
151+
w_val &= ~w_clr;
152+
153+
write_sysreg_s(r_val, SYS_HDFGRTR_EL2);
154+
write_sysreg_s(w_val, SYS_HDFGWTR_EL2);
112155
}
113156

114157
static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
@@ -121,7 +164,12 @@ static inline void __deactivate_traps_hfgxtr(struct kvm_vcpu *vcpu)
121164
write_sysreg_s(ctxt_sys_reg(hctxt, HFGRTR_EL2), SYS_HFGRTR_EL2);
122165
write_sysreg_s(ctxt_sys_reg(hctxt, HFGWTR_EL2), SYS_HFGWTR_EL2);
123166

167+
if (!vcpu_has_nv(vcpu) || is_hyp_ctxt(vcpu))
168+
return;
124169

170+
write_sysreg_s(ctxt_sys_reg(hctxt, HFGITR_EL2), SYS_HFGITR_EL2);
171+
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGRTR_EL2), SYS_HDFGRTR_EL2);
172+
write_sysreg_s(ctxt_sys_reg(hctxt, HDFGWTR_EL2), SYS_HDFGWTR_EL2);
125173
}
126174

127175
static inline void __activate_traps_common(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)