Skip to content

Commit 014c4c7

Browse files
chazyMarc Zyngier
authored andcommitted
KVM: arm64: Improve debug register save/restore flow
Instead of having multiple calls from the world switch path to the debug logic, each figuring out if the dirty bit is set and if we should save/restore the debug registers, let's just provide two hooks to the debug save/restore functionality, one for switching to the guest context, and one for switching to the host context, and we get the benefit of only having to evaluate the dirty flag once on each path, plus we give the compiler some more room to inline some of this functionality. Reviewed-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Andrew Jones <drjones@redhat.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent 5742d04 commit 014c4c7

File tree

3 files changed

+42
-30
lines changed

3 files changed

+42
-30
lines changed

arch/arm64/include/asm/kvm_hyp.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,8 @@ void __sysreg_restore_guest_state(struct kvm_cpu_context *ctxt);
138138
void __sysreg32_save_state(struct kvm_vcpu *vcpu);
139139
void __sysreg32_restore_state(struct kvm_vcpu *vcpu);
140140

141-
void __debug_save_state(struct kvm_vcpu *vcpu,
142-
struct kvm_guest_debug_arch *dbg,
143-
struct kvm_cpu_context *ctxt);
144-
void __debug_restore_state(struct kvm_vcpu *vcpu,
145-
struct kvm_guest_debug_arch *dbg,
146-
struct kvm_cpu_context *ctxt);
147-
void __debug_cond_save_host_state(struct kvm_vcpu *vcpu);
148-
void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu);
141+
void __debug_switch_to_guest(struct kvm_vcpu *vcpu);
142+
void __debug_switch_to_host(struct kvm_vcpu *vcpu);
149143

150144
void __fpsimd_save_state(struct user_fpsimd_state *fp_regs);
151145
void __fpsimd_restore_state(struct user_fpsimd_state *fp_regs);

arch/arm64/kvm/hyp/debug-sr.c

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,13 @@ static void __hyp_text __debug_restore_spe_nvhe(u64 pmscr_el1)
110110
write_sysreg_s(pmscr_el1, SYS_PMSCR_EL1);
111111
}
112112

113-
void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
114-
struct kvm_guest_debug_arch *dbg,
115-
struct kvm_cpu_context *ctxt)
113+
static void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
114+
struct kvm_guest_debug_arch *dbg,
115+
struct kvm_cpu_context *ctxt)
116116
{
117117
u64 aa64dfr0;
118118
int brps, wrps;
119119

120-
if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
121-
return;
122-
123120
aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
124121
brps = (aa64dfr0 >> 12) & 0xf;
125122
wrps = (aa64dfr0 >> 20) & 0xf;
@@ -132,16 +129,13 @@ void __hyp_text __debug_save_state(struct kvm_vcpu *vcpu,
132129
ctxt->sys_regs[MDCCINT_EL1] = read_sysreg(mdccint_el1);
133130
}
134131

135-
void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
136-
struct kvm_guest_debug_arch *dbg,
137-
struct kvm_cpu_context *ctxt)
132+
static void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
133+
struct kvm_guest_debug_arch *dbg,
134+
struct kvm_cpu_context *ctxt)
138135
{
139136
u64 aa64dfr0;
140137
int brps, wrps;
141138

142-
if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
143-
return;
144-
145139
aa64dfr0 = read_sysreg(id_aa64dfr0_el1);
146140

147141
brps = (aa64dfr0 >> 12) & 0xf;
@@ -155,26 +149,52 @@ void __hyp_text __debug_restore_state(struct kvm_vcpu *vcpu,
155149
write_sysreg(ctxt->sys_regs[MDCCINT_EL1], mdccint_el1);
156150
}
157151

158-
void __hyp_text __debug_cond_save_host_state(struct kvm_vcpu *vcpu)
152+
void __hyp_text __debug_switch_to_guest(struct kvm_vcpu *vcpu)
159153
{
160-
__debug_save_state(vcpu, &vcpu->arch.host_debug_state.regs,
161-
kern_hyp_va(vcpu->arch.host_cpu_context));
154+
struct kvm_cpu_context *host_ctxt;
155+
struct kvm_cpu_context *guest_ctxt;
156+
struct kvm_guest_debug_arch *host_dbg;
157+
struct kvm_guest_debug_arch *guest_dbg;
162158

163159
/*
164160
* Non-VHE: Disable and flush SPE data generation
165161
* VHE: The vcpu can run, but it can't hide.
166162
*/
167163
if (!has_vhe())
168164
__debug_save_spe_nvhe(&vcpu->arch.host_debug_state.pmscr_el1);
165+
166+
if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
167+
return;
168+
169+
host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
170+
guest_ctxt = &vcpu->arch.ctxt;
171+
host_dbg = &vcpu->arch.host_debug_state.regs;
172+
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
173+
174+
__debug_save_state(vcpu, host_dbg, host_ctxt);
175+
__debug_restore_state(vcpu, guest_dbg, guest_ctxt);
169176
}
170177

171-
void __hyp_text __debug_cond_restore_host_state(struct kvm_vcpu *vcpu)
178+
void __hyp_text __debug_switch_to_host(struct kvm_vcpu *vcpu)
172179
{
180+
struct kvm_cpu_context *host_ctxt;
181+
struct kvm_cpu_context *guest_ctxt;
182+
struct kvm_guest_debug_arch *host_dbg;
183+
struct kvm_guest_debug_arch *guest_dbg;
184+
173185
if (!has_vhe())
174186
__debug_restore_spe_nvhe(vcpu->arch.host_debug_state.pmscr_el1);
175187

176-
__debug_restore_state(vcpu, &vcpu->arch.host_debug_state.regs,
177-
kern_hyp_va(vcpu->arch.host_cpu_context));
188+
if (!(vcpu->arch.debug_flags & KVM_ARM64_DEBUG_DIRTY))
189+
return;
190+
191+
host_ctxt = kern_hyp_va(vcpu->arch.host_cpu_context);
192+
guest_ctxt = &vcpu->arch.ctxt;
193+
host_dbg = &vcpu->arch.host_debug_state.regs;
194+
guest_dbg = kern_hyp_va(vcpu->arch.debug_ptr);
195+
196+
__debug_save_state(vcpu, guest_dbg, guest_ctxt);
197+
__debug_restore_state(vcpu, host_dbg, host_ctxt);
178198

179199
vcpu->arch.debug_flags &= ~KVM_ARM64_DEBUG_DIRTY;
180200
}

arch/arm64/kvm/hyp/switch.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,6 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
305305
guest_ctxt = &vcpu->arch.ctxt;
306306

307307
__sysreg_save_host_state(host_ctxt);
308-
__debug_cond_save_host_state(vcpu);
309308

310309
__activate_traps(vcpu);
311310
__activate_vm(vcpu);
@@ -319,7 +318,7 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
319318
*/
320319
__sysreg32_restore_state(vcpu);
321320
__sysreg_restore_guest_state(guest_ctxt);
322-
__debug_restore_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
321+
__debug_switch_to_guest(vcpu);
323322

324323
/* Jump in the fire! */
325324
again:
@@ -416,12 +415,11 @@ int __hyp_text __kvm_vcpu_run(struct kvm_vcpu *vcpu)
416415
__fpsimd_restore_state(&host_ctxt->gp_regs.fp_regs);
417416
}
418417

419-
__debug_save_state(vcpu, kern_hyp_va(vcpu->arch.debug_ptr), guest_ctxt);
420418
/*
421419
* This must come after restoring the host sysregs, since a non-VHE
422420
* system may enable SPE here and make use of the TTBRs.
423421
*/
424-
__debug_cond_restore_host_state(vcpu);
422+
__debug_switch_to_host(vcpu);
425423

426424
return exit_code;
427425
}

0 commit comments

Comments
 (0)