[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250902094945.2957566-4-maobibo@loongson.cn>
Date: Tue, 2 Sep 2025 17:49:44 +0800
From: Bibo Mao <maobibo@...ngson.cn>
To: Huacai Chen <chenhuacai@...nel.org>,
Xianglai Li <lixianglai@...ngson.cn>
Cc: WANG Xuerui <kernel@...0n.name>,
kvm@...r.kernel.org,
loongarch@...ts.linux.dev,
linux-kernel@...r.kernel.org
Subject: [PATCH 3/4] LoongArch: KVM: Avoid use copy_from_user with lock hold in kvm_eiointc_ctrl_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 with copy_from_user() and copy_to_user() before spinlock
context in function kvm_eiointc_ctrl_access().
Fixes: 1ad7efa552fd5 ("LoongArch: KVM: Add EIOINTC user mode read and write functions")
Signed-off-by: Bibo Mao <maobibo@...ngson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index dd0477faf8e0..c32333695381 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -426,21 +426,26 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
struct loongarch_eiointc *s = dev->kvm->arch.eiointc;
data = (void __user *)attr->addr;
- spin_lock_irqsave(&s->lock, flags);
switch (type) {
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
+ case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
if (copy_from_user(&val, data, 4))
- ret = -EFAULT;
- else {
- if (val >= EIOINTC_ROUTE_MAX_VCPUS)
- ret = -EINVAL;
- else
- s->num_cpu = val;
- }
+ return -EFAULT;
+ break;
+ default:
+ break;
+ }
+
+ spin_lock_irqsave(&s->lock, flags);
+ switch (type) {
+ case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU:
+ if (val >= EIOINTC_ROUTE_MAX_VCPUS)
+ ret = -EINVAL;
+ else
+ s->num_cpu = val;
break;
case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE:
- if (copy_from_user(&s->features, data, 4))
- ret = -EFAULT;
+ s->features = val;
if (!(s->features & BIT(EIOINTC_HAS_VIRT_EXTENSION)))
s->status |= BIT(EIOINTC_ENABLE);
break;
--
2.39.3
Powered by blists - more mailing lists