Skip to content

Commit 62f1179

Browse files
bibo-maochenhuacai
authored andcommitted
LoongArch: KVM: Avoid copy_*_user() with lock hold in kvm_eiointc_regs_access()
Function copy_from_user() and copy_to_user() may sleep because of page fault, and they cannot be called in spin_lock hold context. Here move function calling of copy_from_user() and copy_to_user() before spinlock context in function kvm_eiointc_ctrl_access(). Otherwise there will be possible warning such as: BUG: sleeping function called from invalid context at include/linux/uaccess.h:192 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 6292, name: qemu-system-loo preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 INFO: lockdep is turned off. irq event stamp: 0 hardirqs last enabled at (0): [<0000000000000000>] 0x0 hardirqs last disabled at (0): [<9000000004c4a554>] copy_process+0x90c/0x1d40 softirqs last enabled at (0): [<9000000004c4a554>] copy_process+0x90c/0x1d40 softirqs last disabled at (0): [<0000000000000000>] 0x0 CPU: 41 UID: 0 PID: 6292 Comm: qemu-system-loo Tainted: G W 6.17.0-rc3+ #31 PREEMPT(full) Tainted: [W]=WARN Stack : 0000000000000076 0000000000000000 9000000004c28264 9000100092ff4000 9000100092ff7b80 9000100092ff7b88 0000000000000000 9000100092ff7cc8 9000100092ff7cc0 9000100092ff7cc0 9000100092ff7a00 0000000000000001 0000000000000001 9000100092ff7b88 947d2f9216a5e8b9 900010008773d880 00000000ffff8b9f fffffffffffffffe 0000000000000ba1 fffffffffffffffe 000000000000003e 900000000825a15b 000010007ad38000 9000100092ff7ec0 0000000000000000 0000000000000000 9000000006f3ac60 9000000007252000 0000000000000000 00007ff746ff2230 0000000000000053 9000200088a021b0 0000555556c9d190 0000000000000000 9000000004c2827c 000055556cfb5f40 00000000000000b0 0000000000000007 0000000000000007 0000000000071c1d Call Trace: [<9000000004c2827c>] show_stack+0x5c/0x180 [<9000000004c20fac>] dump_stack_lvl+0x94/0xe4 [<9000000004c99c7c>] __might_resched+0x26c/0x290 [<9000000004f68968>] __might_fault+0x20/0x88 [<ffff800002311de0>] kvm_eiointc_regs_access.isra.0+0x88/0x380 [kvm] [<ffff8000022f8514>] kvm_device_ioctl+0x194/0x290 [kvm] [<900000000506b0d8>] sys_ioctl+0x388/0x1010 [<90000000063ed210>] do_syscall+0xb0/0x2d8 [<9000000004c25ef8>] handle_syscall+0xb8/0x158 Cc: stable@vger.kernel.org Fixes: 1ad7efa ("LoongArch: KVM: Add EIOINTC user mode read and write functions") Signed-off-by: Bibo Mao <maobibo@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 47256c4 commit 62f1179

File tree

1 file changed

+21
-12
lines changed

1 file changed

+21
-12
lines changed

arch/loongarch/kvm/intc/eiointc.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -467,19 +467,17 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
467467

468468
static int kvm_eiointc_regs_access(struct kvm_device *dev,
469469
struct kvm_device_attr *attr,
470-
bool is_write)
470+
bool is_write, int *data)
471471
{
472472
int addr, cpu, offset, ret = 0;
473473
unsigned long flags;
474474
void *p = NULL;
475-
void __user *data;
476475
struct loongarch_eiointc *s;
477476

478477
s = dev->kvm->arch.eiointc;
479478
addr = attr->attr;
480479
cpu = addr >> 16;
481480
addr &= 0xffff;
482-
data = (void __user *)attr->addr;
483481
switch (addr) {
484482
case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
485483
offset = (addr - EIOINTC_NODETYPE_START) / 4;
@@ -518,13 +516,10 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
518516
}
519517

520518
spin_lock_irqsave(&s->lock, flags);
521-
if (is_write) {
522-
if (copy_from_user(p, data, 4))
523-
ret = -EFAULT;
524-
} else {
525-
if (copy_to_user(data, p, 4))
526-
ret = -EFAULT;
527-
}
519+
if (is_write)
520+
memcpy(p, data, 4);
521+
else
522+
memcpy(data, p, 4);
528523
spin_unlock_irqrestore(&s->lock, flags);
529524

530525
return ret;
@@ -581,9 +576,18 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
581576
static int kvm_eiointc_get_attr(struct kvm_device *dev,
582577
struct kvm_device_attr *attr)
583578
{
579+
int ret, data;
580+
584581
switch (attr->group) {
585582
case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
586-
return kvm_eiointc_regs_access(dev, attr, false);
583+
ret = kvm_eiointc_regs_access(dev, attr, false, &data);
584+
if (ret)
585+
return ret;
586+
587+
if (copy_to_user((void __user *)attr->addr, &data, 4))
588+
ret = -EFAULT;
589+
590+
return ret;
587591
case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
588592
return kvm_eiointc_sw_status_access(dev, attr, false);
589593
default:
@@ -594,11 +598,16 @@ static int kvm_eiointc_get_attr(struct kvm_device *dev,
594598
static int kvm_eiointc_set_attr(struct kvm_device *dev,
595599
struct kvm_device_attr *attr)
596600
{
601+
int data;
602+
597603
switch (attr->group) {
598604
case KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL:
599605
return kvm_eiointc_ctrl_access(dev, attr);
600606
case KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS:
601-
return kvm_eiointc_regs_access(dev, attr, true);
607+
if (copy_from_user(&data, (void __user *)attr->addr, 4))
608+
return -EFAULT;
609+
610+
return kvm_eiointc_regs_access(dev, attr, true, &data);
602611
case KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS:
603612
return kvm_eiointc_sw_status_access(dev, attr, true);
604613
default:

0 commit comments

Comments
 (0)