Skip to content

Commit 5c1ebe9

Browse files
committed
KVM: arm64: Don't initialize idreg debugfs w/ preemption disabled
Testing KVM with DEBUG_ATOMIC_SLEEP enabled doesn't get far before hitting the first splat: BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1578 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 13062, name: vgic_lpi_stress preempt_count: 1, expected: 0 2 locks held by vgic_lpi_stress/13062: #0: ffff080084553240 (&vcpu->mutex){+.+.}-{3:3}, at: kvm_vcpu_ioctl+0xc0/0x13f0 #1: ffff800080485f08 (&kvm->arch.config_lock){+.+.}-{3:3}, at: kvm_arch_vcpu_ioctl+0xd60/0x1788 CPU: 19 PID: 13062 Comm: vgic_lpi_stress Tainted: G W O 6.8.0-dbg-DEV #1 Call trace: dump_backtrace+0xf8/0x148 show_stack+0x20/0x38 dump_stack_lvl+0xb4/0xf8 dump_stack+0x18/0x40 __might_resched+0x248/0x2a0 __might_sleep+0x50/0x88 down_write+0x30/0x150 start_creating+0x90/0x1a0 __debugfs_create_file+0x5c/0x1b0 debugfs_create_file+0x34/0x48 kvm_reset_sys_regs+0x120/0x1e8 kvm_reset_vcpu+0x148/0x270 kvm_arch_vcpu_ioctl+0xddc/0x1788 kvm_vcpu_ioctl+0xb6c/0x13f0 __arm64_sys_ioctl+0x98/0xd8 invoke_syscall+0x48/0x108 el0_svc_common+0xb4/0xf0 do_el0_svc+0x24/0x38 el0_svc+0x54/0x128 el0t_64_sync_handler+0x68/0xc0 el0t_64_sync+0x1a8/0x1b0 kvm_reset_vcpu() disables preemption as it needs to unload vCPU state from the CPU to twiddle with it, which subsequently explodes when taking the parent inode's rwsem while creating the idreg debugfs file. Fix it by moving the initialization to kvm_arch_create_vm_debugfs(). Fixes: 8917665 ("KVM: arm64: Add debugfs file for guest's ID registers") Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 29ef55c commit 5c1ebe9

File tree

3 files changed

+14
-5
lines changed

3 files changed

+14
-5
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,7 @@ int kvm_handle_cp15_64(struct kvm_vcpu *vcpu);
11021102
int kvm_handle_sys_reg(struct kvm_vcpu *vcpu);
11031103
int kvm_handle_cp10_id(struct kvm_vcpu *vcpu);
11041104

1105+
void kvm_sys_regs_create_debugfs(struct kvm *kvm);
11051106
void kvm_reset_sys_regs(struct kvm_vcpu *vcpu);
11061107

11071108
int __init kvm_sys_reg_table_init(void);

arch/arm64/kvm/arm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
190190
return VM_FAULT_SIGBUS;
191191
}
192192

193+
int kvm_arch_create_vm_debugfs(struct kvm *kvm)
194+
{
195+
kvm_sys_regs_create_debugfs(kvm);
196+
return 0;
197+
}
193198

194199
/**
195200
* kvm_arch_destroy_vm - destroy the VM data structure

arch/arm64/kvm/sys_regs.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,14 @@ static const struct seq_operations idregs_debug_sops = {
34993499

35003500
DEFINE_SEQ_ATTRIBUTE(idregs_debug);
35013501

3502+
void kvm_sys_regs_create_debugfs(struct kvm *kvm)
3503+
{
3504+
kvm->arch.idreg_debugfs_iter = ~0;
3505+
3506+
debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
3507+
&idregs_debug_fops);
3508+
}
3509+
35023510
static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
35033511
{
35043512
const struct sys_reg_desc *idreg = first_idreg;
@@ -3518,11 +3526,6 @@ static void kvm_reset_id_regs(struct kvm_vcpu *vcpu)
35183526
id = reg_to_encoding(idreg);
35193527
}
35203528

3521-
kvm->arch.idreg_debugfs_iter = ~0;
3522-
3523-
debugfs_create_file("idregs", 0444, kvm->debugfs_dentry, kvm,
3524-
&idregs_debug_fops);
3525-
35263529
set_bit(KVM_ARCH_FLAG_ID_REGS_INITIALIZED, &kvm->arch.flags);
35273530
}
35283531

0 commit comments

Comments
 (0)