Skip to content

Commit 34fbdee

Browse files
reijiw-kvmMarc Zyngier
authored andcommitted
KVM: arm64: Preserve PSTATE.SS for the guest while single-step is enabled
Preserve the PSTATE.SS value for the guest while userspace enables single-step (i.e. while KVM manipulates the PSTATE.SS) for the vCPU. Currently, while userspace enables single-step for the vCPU (with KVM_GUESTDBG_SINGLESTEP), KVM sets PSTATE.SS to 1 on every guest entry, not saving its original value. When userspace disables single-step, KVM doesn't restore the original value for the subsequent guest entry (use the current value instead). Exception return instructions copy PSTATE.SS from SPSR_ELx.SS only in certain cases when single-step is enabled (and set it to 0 in other cases). So, the value matters only when the guest enables single-step (and when the guest's Software step state isn't affected by single-step enabled by userspace, practically), though. Fix this by preserving the original PSTATE.SS value while userspace enables single-step, and restoring the value once it is disabled. This fix modifies the behavior of GET_ONE_REG/SET_ONE_REG for the PSTATE.SS while single-step is enabled by userspace. Presently, GET_ONE_REG/SET_ONE_REG gets/sets the current PSTATE.SS value, which KVM will override on the next guest entry (i.e. the value userspace gets/sets is not used for the next guest entry). With this patch, GET_ONE_REG/SET_ONE_REG will get/set the guest's preserved value, which KVM will preserve and try to restore after single-step is disabled. Fixes: 337b99b ("KVM: arm64: guest debug, add support for single-step") Signed-off-by: Reiji Watanabe <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent b90cb10 commit 34fbdee

File tree

2 files changed

+13
-0
lines changed

2 files changed

+13
-0
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ struct kvm_vcpu_arch {
393393
*/
394394
struct {
395395
u32 mdscr_el1;
396+
bool pstate_ss;
396397
} guest_debug_preserved;
397398

398399
/* vcpu power state */

arch/arm64/kvm/debug.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ static DEFINE_PER_CPU(u64, mdcr_el2);
3232
*
3333
* Guest access to MDSCR_EL1 is trapped by the hypervisor and handled
3434
* after we have restored the preserved value to the main context.
35+
*
36+
* When single-step is enabled by userspace, we tweak PSTATE.SS on every
37+
* guest entry. Preserve PSTATE.SS so we can restore the original value
38+
* for the vcpu after the single-step is disabled.
3539
*/
3640
static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
3741
{
@@ -41,6 +45,9 @@ static void save_guest_debug_regs(struct kvm_vcpu *vcpu)
4145

4246
trace_kvm_arm_set_dreg32("Saved MDSCR_EL1",
4347
vcpu->arch.guest_debug_preserved.mdscr_el1);
48+
49+
vcpu->arch.guest_debug_preserved.pstate_ss =
50+
(*vcpu_cpsr(vcpu) & DBG_SPSR_SS);
4451
}
4552

4653
static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
@@ -51,6 +58,11 @@ static void restore_guest_debug_regs(struct kvm_vcpu *vcpu)
5158

5259
trace_kvm_arm_set_dreg32("Restored MDSCR_EL1",
5360
vcpu_read_sys_reg(vcpu, MDSCR_EL1));
61+
62+
if (vcpu->arch.guest_debug_preserved.pstate_ss)
63+
*vcpu_cpsr(vcpu) |= DBG_SPSR_SS;
64+
else
65+
*vcpu_cpsr(vcpu) &= ~DBG_SPSR_SS;
5466
}
5567

5668
/**

0 commit comments

Comments
 (0)