Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH v3 0/3] LoongArch: KVM: Harden interrupt injection
@ 2026-06-29  2:32 Bibo Mao
  2026-06-29  2:32 ` [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8 Bibo Mao
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Bibo Mao @ 2026-06-29  2:32 UTC (permalink / raw)
  To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel

API kvm_vcpu_ioctl_interrupt() is mainly to used to deliver interrupt
from user mode, and internal APIs kvm_queue_irq() and kvm_dequeue_irq()
are used in kernel mode, also moves IPI interrupt handling within lock
protection.

Also this patch replaces kvm_err() with WARN_ONCE() to avoid noise
kernel log.

---
v2 ... v3:
  1. Split the patches into three smaller ones, the first patch removes
     old default case and kvm_err() since it is impossible to happen.
     And the second patch replaces kvm_err() with WARN_ONCE().
     
v1 ... v2:
  1. Add border check with ipnum in eiointc_set_sw_coreisr() and
     eiointc_update_irq(), so that injected interrupt vector is valid.

  2. Move IPI inject and ack within lock to avoid contention in
     ipi_set() and ipi_clear().

  3. Add kvm_arch_irqchip_in_kernel() check in user mode irq injection
    in function kvm_vcpu_ioctl_interrupt(), contention of user mode irq
    injection is assured from user mode VMM.
---
Bibo Mao (3):
  LoongArch: KVM: Set default MAILBOX access size with 8
  LoongArch: KVM: Replace kvm_err() with WARN_ONCE()
  LoongArch: KVM: Use internal API to deliver interrupt in kernel mode

 arch/loongarch/kvm/exit.c         | 15 ++++-----
 arch/loongarch/kvm/intc/dmsintc.c | 15 +++++----
 arch/loongarch/kvm/intc/eiointc.c | 32 ++++++++++--------
 arch/loongarch/kvm/intc/ipi.c     | 55 ++++++++++++++-----------------
 arch/loongarch/kvm/intc/pch_pic.c | 12 +++----
 arch/loongarch/kvm/vcpu.c         |  5 ++-
 6 files changed, 67 insertions(+), 67 deletions(-)


base-commit: dc59e4fea9d83f03bad6bddf3fa2e52491777482
-- 
2.39.3


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8
  2026-06-29  2:32 [PATCH v3 0/3] LoongArch: KVM: Harden interrupt injection Bibo Mao
@ 2026-06-29  2:32 ` Bibo Mao
  2026-06-29  2:45   ` sashiko-bot
  2026-06-29  2:32 ` [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE() Bibo Mao
  2026-06-29  2:32 ` [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode Bibo Mao
  2 siblings, 1 reply; 8+ messages in thread
From: Bibo Mao @ 2026-06-29  2:32 UTC (permalink / raw)
  To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel

With IOCSR instruction emulation in function kvm_emu_iocsr(), the possible
size combination is 1/2/4/8 and no other combinations. Here remove the
old default case and replace the default case with 8 in read_mailbox()
and write_mailbox().

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/ipi.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index 4fa0897d7bdb..d70bf415c7fc 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -67,11 +67,8 @@ static uint64_t read_mailbox(struct kvm_vcpu *vcpu, int offset, int len)
 		return data & 0xffff;
 	case 4:
 		return data & 0xffffffff;
-	case 8:
-		return data;
 	default:
-		kvm_err("%s: unknown data len: %d\n", __func__, len);
-		return 0;
+		return data;
 	}
 }
 
@@ -92,11 +89,9 @@ static void write_mailbox(struct kvm_vcpu *vcpu, int offset, uint64_t data, int
 	case 4:
 		*(unsigned int *)pbuf = (unsigned int)data;
 		break;
-	case 8:
+	default:
 		*(unsigned long *)pbuf = (unsigned long)data;
 		break;
-	default:
-		kvm_err("%s: unknown data len: %d\n", __func__, len);
 	}
 	spin_unlock(&vcpu->arch.ipi_state.lock);
 }
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE()
  2026-06-29  2:32 [PATCH v3 0/3] LoongArch: KVM: Harden interrupt injection Bibo Mao
  2026-06-29  2:32 ` [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8 Bibo Mao
@ 2026-06-29  2:32 ` Bibo Mao
  2026-06-29  2:37   ` sashiko-bot
  2026-06-30  4:27   ` Huacai Chen
  2026-06-29  2:32 ` [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode Bibo Mao
  2 siblings, 2 replies; 8+ messages in thread
From: Bibo Mao @ 2026-06-29  2:32 UTC (permalink / raw)
  To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel

Since guest kernel and ioctl parameter from user mode is untrusted,
there may be noise kernel log output in host hypervisor with abnormal
state. Here replace kvm_err() with WARN_ONCE() to reduce this kind
of noise kernel log, and there is no function change.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/exit.c         | 15 +++++++--------
 arch/loongarch/kvm/intc/dmsintc.c |  8 ++++----
 arch/loongarch/kvm/intc/eiointc.c | 18 ++++++++---------
 arch/loongarch/kvm/intc/ipi.c     | 32 +++++++++++++++----------------
 arch/loongarch/kvm/intc/pch_pic.c | 12 ++++++------
 arch/loongarch/kvm/vcpu.c         |  2 +-
 6 files changed, 43 insertions(+), 44 deletions(-)

diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
index 8572b63478bb..4ad006e27a4d 100644
--- a/arch/loongarch/kvm/exit.c
+++ b/arch/loongarch/kvm/exit.c
@@ -252,7 +252,7 @@ int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		*gpr = *(s64 *)run->iocsr_io.data;
 		break;
 	default:
-		kvm_err("Bad IOCSR length: %d, addr is 0x%lx\n",
+		WARN_ONCE(1, "Bad IOCSR length: %d, addr is 0x%lx\n",
 				run->iocsr_io.len, vcpu->arch.badv);
 		er = EMULATE_FAIL;
 		break;
@@ -326,7 +326,7 @@ static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)
 
 	/* Rollback PC only if emulation was unsuccessful */
 	if (er == EMULATE_FAIL) {
-		kvm_err("[%#lx]%s: unsupported gspr instruction 0x%08x\n",
+		WARN_ONCE(1, "[%#lx]%s: unsupported gspr instruction 0x%08x\n",
 			curr_pc, __func__, inst.word);
 
 		kvm_arch_vcpu_dump_regs(vcpu);
@@ -491,7 +491,7 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
 		return EMULATE_DO_MMIO;
 	}
 
-	kvm_err("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
+	WARN_ONCE(1, "Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
 			inst.word, vcpu->arch.pc, vcpu->arch.badv);
 	kvm_arch_vcpu_dump_regs(vcpu);
 	vcpu->mmio_needed = 0;
@@ -529,7 +529,7 @@ int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
 		*gpr = *(s64 *)run->mmio.data;
 		break;
 	default:
-		kvm_err("Bad MMIO length: %d, addr is 0x%lx\n",
+		WARN_ONCE(1, "Bad MMIO length: %d, addr is 0x%lx\n",
 				run->mmio.len, vcpu->arch.badv);
 		er = EMULATE_FAIL;
 		break;
@@ -656,7 +656,7 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
 	}
 
 	vcpu->arch.pc = curr_pc;
-	kvm_err("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
+	WARN_ONCE(1, "Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
 			inst.word, vcpu->arch.pc, vcpu->arch.badv);
 	kvm_arch_vcpu_dump_regs(vcpu);
 	/* Rollback PC if emulation was unsuccessful */
@@ -748,8 +748,7 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode)
 	 * treated as a reserved instruction!
 	 * If FPU already in use, we shouldn't get this at all.
 	 */
-	if (WARN_ON(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) {
-		kvm_err("%s internal error\n", __func__);
+	if (WARN_ON_ONCE(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) {
 		run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 		return RESUME_HOST;
 	}
@@ -943,7 +942,7 @@ static int kvm_fault_ni(struct kvm_vcpu *vcpu, int ecode)
 	/* Fetch the instruction */
 	inst = vcpu->arch.badi;
 	badv = vcpu->arch.badv;
-	kvm_err("ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\n",
+	WARN_ONCE(1, "ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\n",
 			ecode, vcpu->arch.pc, inst, badv, read_gcsr_estat());
 	kvm_arch_vcpu_dump_regs(vcpu);
 	kvm_queue_exception(vcpu, EXCCODE_INE, 0);
diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
index de25735ce039..708abbcd55bf 100644
--- a/arch/loongarch/kvm/intc/dmsintc.c
+++ b/arch/loongarch/kvm/intc/dmsintc.c
@@ -114,7 +114,7 @@ static int kvm_dmsintc_ctrl_access(struct kvm_device *dev,
 		}
 		break;
 	default:
-		kvm_err("%s: unknown dmsintc register, addr = %d\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown dmsintc register, addr = %d\n", __func__, addr);
 		return -ENXIO;
 	}
 
@@ -128,7 +128,7 @@ static int kvm_dmsintc_set_attr(struct kvm_device *dev,
 	case KVM_DEV_LOONGARCH_DMSINTC_GRP_CTRL:
 		return kvm_dmsintc_ctrl_access(dev, attr, true);
 	default:
-		kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
+		WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
 		return -EINVAL;
 	}
 }
@@ -139,13 +139,13 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)
 	struct loongarch_dmsintc *s;
 
 	if (!dev) {
-		kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
+		WARN_ONCE(1, "%s: kvm_device ptr is invalid!\n", __func__);
 		return -EINVAL;
 	}
 
 	kvm = dev->kvm;
 	if (kvm->arch.dmsintc) {
-		kvm_err("%s: LoongArch DMSINTC has already been created!\n", __func__);
+		WARN_ONCE(1, "%s: LoongArch DMSINTC has already been created!\n", __func__);
 		return -EINVAL;
 	}
 
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 2b14485d14a7..555e55246f0c 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -47,7 +47,7 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 	cpu = s->sw_coremap[irq];
 	vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
 	if (unlikely(vcpu == NULL)) {
-		kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+		WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
 		return;
 	}
 
@@ -165,12 +165,12 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
-		kvm_err("%s: eiointc irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
 		return 0;
 	}
 
 	if (addr & (len - 1)) {
-		kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
+		WARN_ONCE(1, "%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
 		return 0;
 	}
 
@@ -297,12 +297,12 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
-		kvm_err("%s: eiointc irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
 		return 0;
 	}
 
 	if (addr & (len - 1)) {
-		kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
+		WARN_ONCE(1, "%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
 		return 0;
 	}
 
@@ -345,7 +345,7 @@ static int kvm_eiointc_virt_read(struct kvm_vcpu *vcpu,
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
-		kvm_err("%s: eiointc irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
 		return 0;
 	}
 
@@ -375,7 +375,7 @@ static int kvm_eiointc_virt_write(struct kvm_vcpu *vcpu,
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
-		kvm_err("%s: eiointc irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
 		return 0;
 	}
 
@@ -502,7 +502,7 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
 		p = (void *)s->coremap + offset * 4;
 		break;
 	default:
-		kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown eiointc register, addr = %d\n", __func__, addr);
 		return -EINVAL;
 	}
 
@@ -546,7 +546,7 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
 		p = &s->status;
 		break;
 	default:
-		kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown eiointc register, addr = %d\n", __func__, addr);
 		return -EINVAL;
 	}
 	spin_lock_irqsave(&s->lock, flags);
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index d70bf415c7fc..8d9dacfc1b15 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -30,7 +30,7 @@ static void ipi_send(struct kvm *kvm, uint64_t data)
 	cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
 	vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
 	if (unlikely(vcpu == NULL)) {
-		kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+		WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
 		return;
 	}
 
@@ -105,7 +105,7 @@ static int mail_send(struct kvm *kvm, uint64_t data)
 	cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
 	vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
 	if (unlikely(vcpu == NULL)) {
-		kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+		WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
 		return 0;
 	}
 	mailbox = ((data & 0xffffffff) >> 2) & 0x7;
@@ -139,7 +139,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
 		ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
 		srcu_read_unlock(&vcpu->kvm->srcu, idx);
 		if (unlikely(ret)) {
-			kvm_err("%s: : read data from addr %llx failed\n", __func__, addr);
+			WARN_ONCE(1, "%s: : read data from addr %llx failed\n", __func__, addr);
 			return 0;
 		}
 		/* Construct the mask by scanning the bit 27-30 */
@@ -155,7 +155,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
 	ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
 	srcu_read_unlock(&vcpu->kvm->srcu, idx);
 	if (unlikely(ret))
-		kvm_err("%s: : write data to addr %llx failed\n", __func__, addr);
+		WARN_ONCE(1, "%s: : write data to addr %llx failed\n", __func__, addr);
 
 	return 0;
 }
@@ -168,7 +168,7 @@ static int any_send(struct kvm *kvm, uint64_t data)
 	cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
 	vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
 	if (unlikely(vcpu == NULL)) {
-		kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+		WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
 		return 0;
 	}
 	offset = data & 0xffff;
@@ -200,14 +200,14 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void
 		break;
 	case IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:
 		if (offset + len > IOCSR_IPI_BUF_38 + 8) {
-			kvm_err("%s: invalid offset or len: offset = %d, len = %d\n",
+			WARN_ONCE(1, "%s: invalid offset or len: offset = %d, len = %d\n",
 				__func__, offset, len);
 			break;
 		}
 		res = read_mailbox(vcpu, offset, len);
 		break;
 	default:
-		kvm_err("%s: unknown addr: %llx\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown addr: %llx\n", __func__, addr);
 		break;
 	}
 	*(uint64_t *)val = res;
@@ -242,7 +242,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
 		break;
 	case IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:
 		if (offset + len > IOCSR_IPI_BUF_38 + 8) {
-			kvm_err("%s: invalid offset or len: offset = %d, len = %d\n",
+			WARN_ONCE(1, "%s: invalid offset or len: offset = %d, len = %d\n",
 				__func__, offset, len);
 			break;
 		}
@@ -258,7 +258,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
 		any_send(vcpu->kvm, data);
 		break;
 	default:
-		kvm_err("%s: unknown addr: %llx\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown addr: %llx\n", __func__, addr);
 		break;
 	}
 
@@ -301,7 +301,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
 
 	vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu);
 	if (unlikely(vcpu == NULL)) {
-		kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+		WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
 		return -EINVAL;
 	}
 
@@ -335,7 +335,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
 		len = 8;
 		break;
 	default:
-		kvm_err("%s: unknown ipi register, addr = %d\n", __func__, addr);
+		WARN_ONCE(1, "%s: unknown ipi register, addr = %d\n", __func__, addr);
 		return -EINVAL;
 	}
 
@@ -369,7 +369,7 @@ static int kvm_ipi_get_attr(struct kvm_device *dev,
 	case KVM_DEV_LOONGARCH_IPI_GRP_REGS:
 		return kvm_ipi_regs_access(dev, attr, false);
 	default:
-		kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
+		WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
 		return -EINVAL;
 	}
 }
@@ -381,7 +381,7 @@ static int kvm_ipi_set_attr(struct kvm_device *dev,
 	case KVM_DEV_LOONGARCH_IPI_GRP_REGS:
 		return kvm_ipi_regs_access(dev, attr, true);
 	default:
-		kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
+		WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
 		return -EINVAL;
 	}
 }
@@ -394,13 +394,13 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)
 	struct loongarch_ipi *s;
 
 	if (!dev) {
-		kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
+		WARN_ONCE(1, "%s: kvm_device ptr is invalid!\n", __func__);
 		return -EINVAL;
 	}
 
 	kvm = dev->kvm;
 	if (kvm->arch.ipi) {
-		kvm_err("%s: LoongArch IPI has already been created!\n", __func__);
+		WARN_ONCE(1, "%s: LoongArch IPI has already been created!\n", __func__);
 		return -EINVAL;
 	}
 
@@ -420,7 +420,7 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)
 	ret = kvm_io_bus_register_dev(kvm, KVM_IOCSR_BUS, IOCSR_IPI_BASE, IOCSR_IPI_SIZE, device);
 	mutex_unlock(&kvm->slots_lock);
 	if (ret < 0) {
-		kvm_err("%s: Initialize IOCSR dev failed, ret = %d\n", __func__, ret);
+		WARN_ONCE(1, "%s: Initialize IOCSR dev failed, ret = %d\n", __func__, ret);
 		goto err;
 	}
 
diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
index 175a630aceb4..299b4db26833 100644
--- a/arch/loongarch/kvm/intc/pch_pic.c
+++ b/arch/loongarch/kvm/intc/pch_pic.c
@@ -151,12 +151,12 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
 	struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;
 
 	if (!s) {
-		kvm_err("%s: pch pic irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: pch pic irqchip not valid!\n", __func__);
 		return ret;
 	}
 
 	if (addr & (len - 1)) {
-		kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
+		WARN_ONCE(1, "%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
 		return ret;
 	}
 
@@ -250,12 +250,12 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
 	struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;
 
 	if (!s) {
-		kvm_err("%s: pch pic irqchip not valid!\n", __func__);
+		WARN_ONCE(1, "%s: pch pic irqchip not valid!\n", __func__);
 		return ret;
 	}
 
 	if (addr & (len - 1)) {
-		kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
+		WARN_ONCE(1, "%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
 		return ret;
 	}
 
@@ -390,13 +390,13 @@ static int kvm_pch_pic_set_attr(struct kvm_device *dev,
 				return -EFAULT;
 
 			if (!dev->kvm->arch.pch_pic) {
-				kvm_err("%s: please create pch_pic irqchip first!\n", __func__);
+				WARN_ONCE(1, "%s: please create pch_pic irqchip first\n", __func__);
 				return -ENODEV;
 			}
 
 			return kvm_pch_pic_init(dev, addr);
 		default:
-			kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
+			WARN_ONCE(1, "%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
 					attr->attr);
 			return -EINVAL;
 		}
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 20c207d80e31..361fca46e2b3 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -1473,7 +1473,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
 	else if (intr < 0)
 		kvm_dequeue_irq(vcpu, -intr);
 	else {
-		kvm_err("%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
+		WARN_ONCE(1, "%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
 		return -EINVAL;
 	}
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode
  2026-06-29  2:32 [PATCH v3 0/3] LoongArch: KVM: Harden interrupt injection Bibo Mao
  2026-06-29  2:32 ` [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8 Bibo Mao
  2026-06-29  2:32 ` [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE() Bibo Mao
@ 2026-06-29  2:32 ` Bibo Mao
  2026-06-29  2:41   ` sashiko-bot
  2 siblings, 1 reply; 8+ messages in thread
From: Bibo Mao @ 2026-06-29  2:32 UTC (permalink / raw)
  To: Huacai Chen; +Cc: kvm, loongarch, linux-kernel

API kvm_vcpu_ioctl_interrupt() is mainly to used to deliver interrupt
from user mode, and internal APIs kvm_queue_irq() and kvm_dequeue_irq()
are used in kernel mode.

Also move IPI inject and ack within lock protection to avoid contention
in ipi_set() and ipi_clear().

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/dmsintc.c |  7 ++++---
 arch/loongarch/kvm/intc/eiointc.c | 14 +++++++++-----
 arch/loongarch/kvm/intc/ipi.c     | 14 ++++++--------
 arch/loongarch/kvm/vcpu.c         |  3 +++
 4 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
index 708abbcd55bf..ed8553224775 100644
--- a/arch/loongarch/kvm/intc/dmsintc.c
+++ b/arch/loongarch/kvm/intc/dmsintc.c
@@ -47,7 +47,6 @@ void dmsintc_inject_irq(struct kvm_vcpu *vcpu)
 int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm,
 				struct kvm_vcpu *vcpu, u32 vector, int level)
 {
-	struct kvm_interrupt vcpu_irq;
 	struct dmsintc_state *ds = &vcpu->arch.dmsintc_state;
 
 	if (!level)
@@ -57,9 +56,11 @@ int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm,
 	if (!ds)
 		return -ENODEV;
 
-	vcpu_irq.irq = INT_AVEC;
+	if (!kvm_guest_has_msgint(&vcpu->arch))
+		return -EINVAL;
+
 	set_bit(vector, (unsigned long *)&ds->vector_map);
-	kvm_vcpu_ioctl_interrupt(vcpu, &vcpu_irq);
+	kvm_queue_irq(vcpu, INT_AVEC);
 	kvm_vcpu_kick(vcpu);
 
 	return 0;
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 555e55246f0c..681dfb548dbf 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -17,7 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 		if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
 			ipnum = count_trailing_zeros(ipnum);
 			ipnum = ipnum < 4 ? ipnum : 0;
-		}
+		} else if (ipnum >= LOONGSON_IP_NUM)
+			ipnum = 0;
 
 		cpuid = ((u8 *)s->coremap)[irq];
 		vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
@@ -36,13 +37,13 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 {
 	int ipnum, cpu, found;
 	struct kvm_vcpu *vcpu;
-	struct kvm_interrupt vcpu_irq;
 
 	ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;
 	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
 		ipnum = count_trailing_zeros(ipnum);
 		ipnum = ipnum < 4 ? ipnum : 0;
-	}
+	} else if (ipnum >= LOONGSON_IP_NUM)
+		ipnum = 0;
 
 	cpu = s->sw_coremap[irq];
 	vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
@@ -67,8 +68,11 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 	if (found < EIOINTC_IRQS)
 		return; /* other irq is handling, needn't update parent irq */
 
-	vcpu_irq.irq = level ? (INT_HWI0 + ipnum) : -(INT_HWI0 + ipnum);
-	kvm_vcpu_ioctl_interrupt(vcpu, &vcpu_irq);
+	if (level)
+		kvm_queue_irq(vcpu, INT_HWI0 + ipnum);
+	else
+		kvm_dequeue_irq(vcpu, INT_HWI0 + ipnum);
+	kvm_vcpu_kick(vcpu);
 }
 
 static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index 8d9dacfc1b15..eacf2073c603 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -10,16 +10,15 @@
 static void ipi_set(struct kvm_vcpu *vcpu, uint32_t data)
 {
 	uint32_t status;
-	struct kvm_interrupt irq;
 
 	spin_lock(&vcpu->arch.ipi_state.lock);
 	status = vcpu->arch.ipi_state.status;
 	vcpu->arch.ipi_state.status |= data;
-	spin_unlock(&vcpu->arch.ipi_state.lock);
 	if ((status == 0) && data) {
-		irq.irq = LARCH_INT_IPI;
-		kvm_vcpu_ioctl_interrupt(vcpu, &irq);
+		kvm_queue_irq(vcpu, LARCH_INT_IPI);
+		kvm_vcpu_kick(vcpu);
 	}
+	spin_unlock(&vcpu->arch.ipi_state.lock);
 }
 
 static void ipi_send(struct kvm *kvm, uint64_t data)
@@ -40,16 +39,15 @@ static void ipi_send(struct kvm *kvm, uint64_t data)
 static void ipi_clear(struct kvm_vcpu *vcpu, uint64_t data)
 {
 	uint32_t status;
-	struct kvm_interrupt irq;
 
 	spin_lock(&vcpu->arch.ipi_state.lock);
 	vcpu->arch.ipi_state.status &= ~data;
 	status = vcpu->arch.ipi_state.status;
-	spin_unlock(&vcpu->arch.ipi_state.lock);
 	if (status == 0) {
-		irq.irq = -LARCH_INT_IPI;
-		kvm_vcpu_ioctl_interrupt(vcpu, &irq);
+		kvm_dequeue_irq(vcpu, LARCH_INT_IPI);
+		kvm_vcpu_kick(vcpu);
 	}
+	spin_unlock(&vcpu->arch.ipi_state.lock);
 }
 
 static uint64_t read_mailbox(struct kvm_vcpu *vcpu, int offset, int len)
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 361fca46e2b3..265aaad63315 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -1465,6 +1465,9 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
 	if (vector >= EXCCODE_INT_NUM)
 		return -EINVAL;
 
+	if (kvm_arch_irqchip_in_kernel(vcpu->kvm))
+		return -EINVAL;
+
 	if (!kvm_guest_has_msgint(&vcpu->arch) && (vector == INT_AVEC))
 		return -EINVAL;
 
-- 
2.39.3


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE()
  2026-06-29  2:32 ` [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE() Bibo Mao
@ 2026-06-29  2:37   ` sashiko-bot
  2026-06-30  4:27   ` Huacai Chen
  1 sibling, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-06-29  2:37 UTC (permalink / raw)
  To: Bibo Mao; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] Replacing `kvm_err()` with `WARN_ONCE()` on user- and guest-controllable error paths introduces a host Denial of Service (DoS) vulnerability.
--

commit 2fb4171bf923d0f32f53ed0ef52aee506acd81c3
Author: Bibo Mao <maobibo@loongson.cn>

LoongArch: KVM: Replace kvm_err() with WARN_ONCE()

Since guest kernel and ioctl parameter from user mode is untrusted,
there may be noise kernel log output in host hypervisor with abnormal
state. Here replace kvm_err() with WARN_ONCE() to reduce this kind
of noise kernel log, and there is no function change.

> diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
> --- a/arch/loongarch/kvm/exit.c
> +++ b/arch/loongarch/kvm/exit.c
> @@ -252,7 +252,7 @@ int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  		*gpr = *(s64 *)run->iocsr_io.data;
>  		break;
>  	default:
> -		kvm_err("Bad IOCSR length: %d, addr is 0x%lx\n",
> +		WARN_ONCE(1, "Bad IOCSR length: %d, addr is 0x%lx\n",
>  				run->iocsr_io.len, vcpu->arch.badv);

[Severity: Critical]
Does changing this to a WARN_ONCE() introduce a host denial of service
vector? A malicious guest executing an operation with a bad IOCSR length
can trigger this path in kvm_complete_iocsr_read().

If the host system is configured with panic_on_warn=1, this allows an
untrusted guest to crash the host. Could this be changed to pr_warn_once()
or pr_err_ratelimited() instead to reduce the log spam without the risk
of a kernel panic?

[ ... ]

> diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
> --- a/arch/loongarch/kvm/intc/dmsintc.c
> +++ b/arch/loongarch/kvm/intc/dmsintc.c
> @@ -114,7 +114,7 @@ static int kvm_dmsintc_ctrl_access(struct kvm_device *dev,
>  		}
>  		break;
>  	default:
> -		kvm_err("%s: unknown dmsintc register, addr = %d\n", __func__, addr);
> +		WARN_ONCE(1, "%s: unknown dmsintc register, addr = %d\n", __func__, addr);

[Severity: Critical]
Similarly here, can a host userspace process trigger this WARN_ONCE by
passing an invalid address to KVM_SET_DEVICE_ATTR for the dmsintc device?

This would allow an unprivileged host userspace process to crash the host
if panic_on_warn=1 is set.

[ ... ]

> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -1473,7 +1473,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
>  	else if (intr < 0)
>  		kvm_dequeue_irq(vcpu, -intr);
>  	else {
> -		kvm_err("%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
> +		WARN_ONCE(1, "%s: invalid interrupt ioctl %d\n", __func__, irq->irq);

[Severity: Critical]
Does this also allow unprivileged userspace to trigger a warning via a
bad interrupt ioctl parameter?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629023213.597030-1-maobibo@loongson.cn?part=2

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode
  2026-06-29  2:32 ` [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode Bibo Mao
@ 2026-06-29  2:41   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-06-29  2:41 UTC (permalink / raw)
  To: Bibo Mao; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Multiple pre-existing WARN_ONCE and WARN_ON_ONCE macros are reachable by unprivileged host userspace and malicious guests, allowing a host-side DoS if `panic_on_warn` is enabled.
- [High] Uninitialized array `vector` is conditionally assigned but unconditionally evaluated and used to modify hardware CSRs.
--

commit f75612ad87b1cded57456f721c300aad7e8b6150
Author: Bibo Mao <maobibo@loongson.cn>

LoongArch: KVM: Use internal API to deliver interrupt in kernel mode
    
This commit updates KVM on LoongArch to use internal APIs
kvm_queue_irq() and kvm_dequeue_irq() for delivering interrupts in kernel
mode, rather than the user mode kvm_vcpu_ioctl_interrupt(). It also moves
IPI injection and ack operations within lock protection to reduce contention.

> diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
> index 708abbcd55bff..ed85532247759 100644
> --- a/arch/loongarch/kvm/intc/dmsintc.c
> +++ b/arch/loongarch/kvm/intc/dmsintc.c
> @@ -47,7 +47,6 @@ void dmsintc_inject_irq(struct kvm_vcpu *vcpu)

[Severity: High]
This isn't a bug introduced by this patch, but looking at dmsintc_inject_irq()
just above this change, is the vector array properly initialized?

arch/loongarch/kvm/intc/dmsintc.c:dmsintc_inject_irq() {
        unsigned long vector[4], old;
        ...
        for (i = 0; i < 4; i++) {
                old = atomic64_read(&(ds->vector_map[i]));
                if (old)
                        vector[i] = atomic64_xchg(&(ds->vector_map[i]), 0);
        }

        if (vector[0]) {
                old = kvm_read_hw_gcsr(LOONGARCH_CSR_ISR0);
                kvm_write_hw_gcsr(LOONGARCH_CSR_ISR0, vector[0] | old);
        }
}

If atomic64_read() returns zero, vector[i] is left uninitialized. When it
checks if (vector[0]) later, could this evaluate to true using stack garbage
and write random data into the guest CSRs?

>  int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm,
>  				struct kvm_vcpu *vcpu, u32 vector, int level)
>  {

[ ... ]

> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 361fca46e2b32..265aaad633157 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -1465,6 +1465,9 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
>  	if (vector >= EXCCODE_INT_NUM)
>  		return -EINVAL;
>  
> +	if (kvm_arch_irqchip_in_kernel(vcpu->kvm))
> +		return -EINVAL;
> +

[Severity: High]
This is a pre-existing issue, but I noticed there are several WARN_ONCE and
WARN_ON_ONCE macros reachable by unprivileged host userspace and malicious
guests in this subsystem.

For example, in kvm_vcpu_ioctl_interrupt(), providing an intr == 0
unconditionally hits a fallback block that calls:

WARN_ONCE(1, "%s: invalid interrupt ioctl %d\n", __func__, irq->irq);

Similarly, in ipi_send() and eiointc_update_irq(), guest-controlled CPU IDs
can yield a NULL vCPU, directly triggering:

WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);

And in loongarch_ipi_readl(), a guest unaligned MMIO read triggers:

WARN_ON_ONCE(offset & (len - 1));

Could these be converted to pr_warn_once(), return an error, or drop the
assertions entirely? These could allow a host-side denial of service if
panic_on_warn is enabled.

>  	if (!kvm_guest_has_msgint(&vcpu->arch) && (vector == INT_AVEC))
>  		return -EINVAL;
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629023213.597030-1-maobibo@loongson.cn?part=3

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8
  2026-06-29  2:32 ` [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8 Bibo Mao
@ 2026-06-29  2:45   ` sashiko-bot
  0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-06-29  2:45 UTC (permalink / raw)
  To: Bibo Mao; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Guest-triggerable Host Denial of Service via WARN_ONCE assertions.

Pre-existing issues:
- [High] Guest-triggerable Host Denial of Service via WARN_ON_ONCE on unaligned IOCSR access.
- [High] Slab-Out-Of-Bounds memory read in `read_mailbox()` causes KASAN panic.
--

commit cd8b88f78bdc2b7a47541c3fb91dfaf558c8c761
Author: Bibo Mao <maobibo@loongson.cn>
Date:   Mon Jun 29 02:32:11 2026 +0000

    LoongArch: KVM: Set default MAILBOX access size with 8
    
    With IOCSR instruction emulation in function kvm_emu_iocsr(), the possible
    size combination is 1/2/4/8 and no other combinations. Here remove the
    old default case and replace the default case with 8 in read_mailbox()
    and write_mailbox().
    
    Signed-off-by: Bibo Mao <maobibo@loongson.cn>

> diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
> index 4fa0897d7bdb0..d70bf415c7fc6 100644
> --- a/arch/loongarch/kvm/intc/ipi.c
> +++ b/arch/loongarch/kvm/intc/ipi.c
> @@ -67,11 +67,8 @@ static uint64_t read_mailbox(struct kvm_vcpu *vcpu, int offset, int len)
>  		return data & 0xffff;
>  	case 4:
>  		return data & 0xffffffff;
> -	case 8:
> -		return data;
>  	default:
> -		kvm_err("%s: unknown data len: %d\n", __func__, len);
> -		return 0;
> +		return data;
>  	}
>  }

[Severity: High]
This is a pre-existing issue, but does read_mailbox() unconditionally read 8
bytes from the buffer, exceeding the 32-byte bounds if the requested offset
and length approach the end of the allowed range (e.g., offset 0x3c with
length 4)?

Looking at read_mailbox():

    arch/loongarch/kvm/intc/ipi.c:read_mailbox() {
        ...
        spin_lock(&vcpu->arch.ipi_state.lock);
        data = *(ulong *)((void *)vcpu->arch.ipi_state.buf + (offset - 0x20));
        spin_unlock(&vcpu->arch.ipi_state.lock);
        ...

A guest performing a valid 4-byte IOCSR read at offset 0x3c causes
read_mailbox() to calculate the array index as 0x1c (28). Dereferencing an
8-byte ulong pointer from this index within the 32-byte
vcpu->arch.ipi_state.buf array reads bytes 28 through 35, where bytes 32-35
fall outside the bounds of the array into adjacent fields in struct
kvm_vcpu_arch. Could this out-of-bounds memory read trigger a KASAN panic,
causing a host denial of service?

[Severity: High]
This is a pre-existing issue, but can an unprivileged guest trigger a host
denial of service via WARN_ON_ONCE on unaligned IOCSR access?

Looking at loongarch_ipi_readl() and loongarch_ipi_writel():

    arch/loongarch/kvm/intc/ipi.c:loongarch_ipi_readl() {
        ...
        offset = (uint32_t)(addr & 0x1ff);
        WARN_ON_ONCE(offset & (len - 1));
        ...

If a guest executes an IOCSR instruction with an unaligned address (e.g.,
iocsrrd.w at address 0x1001), the hardware/emulated offset is calculated as
addr & 0x1ff, which will be unaligned. This causes the
WARN_ON_ONCE(offset & (len - 1)) assertion to fire, which can panic the host
kernel if panic_on_warn is enabled.

[Severity: High]
While the intention may have been to reduce log spam by replacing kvm_err()
with WARN_ONCE(), does this inadvertently create a denial of service vector?

Looking at mail_send() in arch/loongarch/kvm/intc/ipi.c:

    arch/loongarch/kvm/intc/ipi.c:mail_send() {
        ...
        if (unlikely(vcpu == NULL)) {
            WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
            return 0;
        }
        ...

And in kvm_complete_iocsr_read() in arch/loongarch/kvm/exit.c:

    arch/loongarch/kvm/exit.c:kvm_complete_iocsr_read() {
        ...
        default:
            WARN_ONCE(1, "Bad IOCSR length: %d, addr is 0x%lx\n", run->iocsr_io.len, vcpu->arch.badv);
            er = EMULATE_FAIL;
        ...

An unprivileged guest can deliberately provide invalid inputs (e.g., an
unknown IOCSR address, an invalid target CPU ID for a mailbox send, or an
unsupported MMIO length). This causes the emulation handlers to hit these
WARN_ONCE() macros. Could this allow a malicious guest to trigger a kernel
panic if panic_on_warn is enabled?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260629023213.597030-1-maobibo@loongson.cn?part=1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE()
  2026-06-29  2:32 ` [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE() Bibo Mao
  2026-06-29  2:37   ` sashiko-bot
@ 2026-06-30  4:27   ` Huacai Chen
  1 sibling, 0 replies; 8+ messages in thread
From: Huacai Chen @ 2026-06-30  4:27 UTC (permalink / raw)
  To: Bibo Mao; +Cc: kvm, loongarch, linux-kernel

Hi, Bibo,

On Mon, Jun 29, 2026 at 10:32 AM Bibo Mao <maobibo@loongson.cn> wrote:
>
> Since guest kernel and ioctl parameter from user mode is untrusted,
> there may be noise kernel log output in host hypervisor with abnormal
> state. Here replace kvm_err() with WARN_ONCE() to reduce this kind
> of noise kernel log, and there is no function change.
Maybe kvm_pr_unimpl() is a little better than WARN_ONCE()? At least it
is a KVM API.

Huacai
>
> Signed-off-by: Bibo Mao <maobibo@loongson.cn>
> ---
>  arch/loongarch/kvm/exit.c         | 15 +++++++--------
>  arch/loongarch/kvm/intc/dmsintc.c |  8 ++++----
>  arch/loongarch/kvm/intc/eiointc.c | 18 ++++++++---------
>  arch/loongarch/kvm/intc/ipi.c     | 32 +++++++++++++++----------------
>  arch/loongarch/kvm/intc/pch_pic.c | 12 ++++++------
>  arch/loongarch/kvm/vcpu.c         |  2 +-
>  6 files changed, 43 insertions(+), 44 deletions(-)
>
> diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
> index 8572b63478bb..4ad006e27a4d 100644
> --- a/arch/loongarch/kvm/exit.c
> +++ b/arch/loongarch/kvm/exit.c
> @@ -252,7 +252,7 @@ int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
>                 *gpr = *(s64 *)run->iocsr_io.data;
>                 break;
>         default:
> -               kvm_err("Bad IOCSR length: %d, addr is 0x%lx\n",
> +               WARN_ONCE(1, "Bad IOCSR length: %d, addr is 0x%lx\n",
>                                 run->iocsr_io.len, vcpu->arch.badv);
>                 er = EMULATE_FAIL;
>                 break;
> @@ -326,7 +326,7 @@ static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)
>
>         /* Rollback PC only if emulation was unsuccessful */
>         if (er == EMULATE_FAIL) {
> -               kvm_err("[%#lx]%s: unsupported gspr instruction 0x%08x\n",
> +               WARN_ONCE(1, "[%#lx]%s: unsupported gspr instruction 0x%08x\n",
>                         curr_pc, __func__, inst.word);
>
>                 kvm_arch_vcpu_dump_regs(vcpu);
> @@ -491,7 +491,7 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)
>                 return EMULATE_DO_MMIO;
>         }
>
> -       kvm_err("Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
> +       WARN_ONCE(1, "Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
>                         inst.word, vcpu->arch.pc, vcpu->arch.badv);
>         kvm_arch_vcpu_dump_regs(vcpu);
>         vcpu->mmio_needed = 0;
> @@ -529,7 +529,7 @@ int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run)
>                 *gpr = *(s64 *)run->mmio.data;
>                 break;
>         default:
> -               kvm_err("Bad MMIO length: %d, addr is 0x%lx\n",
> +               WARN_ONCE(1, "Bad MMIO length: %d, addr is 0x%lx\n",
>                                 run->mmio.len, vcpu->arch.badv);
>                 er = EMULATE_FAIL;
>                 break;
> @@ -656,7 +656,7 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)
>         }
>
>         vcpu->arch.pc = curr_pc;
> -       kvm_err("Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
> +       WARN_ONCE(1, "Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\n",
>                         inst.word, vcpu->arch.pc, vcpu->arch.badv);
>         kvm_arch_vcpu_dump_regs(vcpu);
>         /* Rollback PC if emulation was unsuccessful */
> @@ -748,8 +748,7 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode)
>          * treated as a reserved instruction!
>          * If FPU already in use, we shouldn't get this at all.
>          */
> -       if (WARN_ON(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) {
> -               kvm_err("%s internal error\n", __func__);
> +       if (WARN_ON_ONCE(vcpu->arch.aux_inuse & KVM_LARCH_FPU)) {
>                 run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
>                 return RESUME_HOST;
>         }
> @@ -943,7 +942,7 @@ static int kvm_fault_ni(struct kvm_vcpu *vcpu, int ecode)
>         /* Fetch the instruction */
>         inst = vcpu->arch.badi;
>         badv = vcpu->arch.badv;
> -       kvm_err("ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\n",
> +       WARN_ONCE(1, "ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\n",
>                         ecode, vcpu->arch.pc, inst, badv, read_gcsr_estat());
>         kvm_arch_vcpu_dump_regs(vcpu);
>         kvm_queue_exception(vcpu, EXCCODE_INE, 0);
> diff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c
> index de25735ce039..708abbcd55bf 100644
> --- a/arch/loongarch/kvm/intc/dmsintc.c
> +++ b/arch/loongarch/kvm/intc/dmsintc.c
> @@ -114,7 +114,7 @@ static int kvm_dmsintc_ctrl_access(struct kvm_device *dev,
>                 }
>                 break;
>         default:
> -               kvm_err("%s: unknown dmsintc register, addr = %d\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown dmsintc register, addr = %d\n", __func__, addr);
>                 return -ENXIO;
>         }
>
> @@ -128,7 +128,7 @@ static int kvm_dmsintc_set_attr(struct kvm_device *dev,
>         case KVM_DEV_LOONGARCH_DMSINTC_GRP_CTRL:
>                 return kvm_dmsintc_ctrl_access(dev, attr, true);
>         default:
> -               kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
> +               WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
>                 return -EINVAL;
>         }
>  }
> @@ -139,13 +139,13 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)
>         struct loongarch_dmsintc *s;
>
>         if (!dev) {
> -               kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
> +               WARN_ONCE(1, "%s: kvm_device ptr is invalid!\n", __func__);
>                 return -EINVAL;
>         }
>
>         kvm = dev->kvm;
>         if (kvm->arch.dmsintc) {
> -               kvm_err("%s: LoongArch DMSINTC has already been created!\n", __func__);
> +               WARN_ONCE(1, "%s: LoongArch DMSINTC has already been created!\n", __func__);
>                 return -EINVAL;
>         }
>
> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
> index 2b14485d14a7..555e55246f0c 100644
> --- a/arch/loongarch/kvm/intc/eiointc.c
> +++ b/arch/loongarch/kvm/intc/eiointc.c
> @@ -47,7 +47,7 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>         cpu = s->sw_coremap[irq];
>         vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
>         if (unlikely(vcpu == NULL)) {
> -               kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
> +               WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
>                 return;
>         }
>
> @@ -165,12 +165,12 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
>         struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
>
>         if (!eiointc) {
> -               kvm_err("%s: eiointc irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
>                 return 0;
>         }
>
>         if (addr & (len - 1)) {
> -               kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
> +               WARN_ONCE(1, "%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
>                 return 0;
>         }
>
> @@ -297,12 +297,12 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
>         struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
>
>         if (!eiointc) {
> -               kvm_err("%s: eiointc irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
>                 return 0;
>         }
>
>         if (addr & (len - 1)) {
> -               kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
> +               WARN_ONCE(1, "%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
>                 return 0;
>         }
>
> @@ -345,7 +345,7 @@ static int kvm_eiointc_virt_read(struct kvm_vcpu *vcpu,
>         struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
>
>         if (!eiointc) {
> -               kvm_err("%s: eiointc irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
>                 return 0;
>         }
>
> @@ -375,7 +375,7 @@ static int kvm_eiointc_virt_write(struct kvm_vcpu *vcpu,
>         struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
>
>         if (!eiointc) {
> -               kvm_err("%s: eiointc irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: eiointc irqchip not valid!\n", __func__);
>                 return 0;
>         }
>
> @@ -502,7 +502,7 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
>                 p = (void *)s->coremap + offset * 4;
>                 break;
>         default:
> -               kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown eiointc register, addr = %d\n", __func__, addr);
>                 return -EINVAL;
>         }
>
> @@ -546,7 +546,7 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,
>                 p = &s->status;
>                 break;
>         default:
> -               kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown eiointc register, addr = %d\n", __func__, addr);
>                 return -EINVAL;
>         }
>         spin_lock_irqsave(&s->lock, flags);
> diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
> index d70bf415c7fc..8d9dacfc1b15 100644
> --- a/arch/loongarch/kvm/intc/ipi.c
> +++ b/arch/loongarch/kvm/intc/ipi.c
> @@ -30,7 +30,7 @@ static void ipi_send(struct kvm *kvm, uint64_t data)
>         cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
>         vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
>         if (unlikely(vcpu == NULL)) {
> -               kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
> +               WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
>                 return;
>         }
>
> @@ -105,7 +105,7 @@ static int mail_send(struct kvm *kvm, uint64_t data)
>         cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
>         vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
>         if (unlikely(vcpu == NULL)) {
> -               kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
> +               WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
>                 return 0;
>         }
>         mailbox = ((data & 0xffffffff) >> 2) & 0x7;
> @@ -139,7 +139,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
>                 ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
>                 srcu_read_unlock(&vcpu->kvm->srcu, idx);
>                 if (unlikely(ret)) {
> -                       kvm_err("%s: : read data from addr %llx failed\n", __func__, addr);
> +                       WARN_ONCE(1, "%s: : read data from addr %llx failed\n", __func__, addr);
>                         return 0;
>                 }
>                 /* Construct the mask by scanning the bit 27-30 */
> @@ -155,7 +155,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)
>         ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, &val);
>         srcu_read_unlock(&vcpu->kvm->srcu, idx);
>         if (unlikely(ret))
> -               kvm_err("%s: : write data to addr %llx failed\n", __func__, addr);
> +               WARN_ONCE(1, "%s: : write data to addr %llx failed\n", __func__, addr);
>
>         return 0;
>  }
> @@ -168,7 +168,7 @@ static int any_send(struct kvm *kvm, uint64_t data)
>         cpu = ((data & 0xffffffff) >> 16) & 0x3ff;
>         vcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);
>         if (unlikely(vcpu == NULL)) {
> -               kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
> +               WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
>                 return 0;
>         }
>         offset = data & 0xffff;
> @@ -200,14 +200,14 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void
>                 break;
>         case IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:
>                 if (offset + len > IOCSR_IPI_BUF_38 + 8) {
> -                       kvm_err("%s: invalid offset or len: offset = %d, len = %d\n",
> +                       WARN_ONCE(1, "%s: invalid offset or len: offset = %d, len = %d\n",
>                                 __func__, offset, len);
>                         break;
>                 }
>                 res = read_mailbox(vcpu, offset, len);
>                 break;
>         default:
> -               kvm_err("%s: unknown addr: %llx\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown addr: %llx\n", __func__, addr);
>                 break;
>         }
>         *(uint64_t *)val = res;
> @@ -242,7 +242,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
>                 break;
>         case IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:
>                 if (offset + len > IOCSR_IPI_BUF_38 + 8) {
> -                       kvm_err("%s: invalid offset or len: offset = %d, len = %d\n",
> +                       WARN_ONCE(1, "%s: invalid offset or len: offset = %d, len = %d\n",
>                                 __func__, offset, len);
>                         break;
>                 }
> @@ -258,7 +258,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
>                 any_send(vcpu->kvm, data);
>                 break;
>         default:
> -               kvm_err("%s: unknown addr: %llx\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown addr: %llx\n", __func__, addr);
>                 break;
>         }
>
> @@ -301,7 +301,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
>
>         vcpu = kvm_get_vcpu_by_id(dev->kvm, cpu);
>         if (unlikely(vcpu == NULL)) {
> -               kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
> +               WARN_ONCE(1, "%s: invalid target cpu: %d\n", __func__, cpu);
>                 return -EINVAL;
>         }
>
> @@ -335,7 +335,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,
>                 len = 8;
>                 break;
>         default:
> -               kvm_err("%s: unknown ipi register, addr = %d\n", __func__, addr);
> +               WARN_ONCE(1, "%s: unknown ipi register, addr = %d\n", __func__, addr);
>                 return -EINVAL;
>         }
>
> @@ -369,7 +369,7 @@ static int kvm_ipi_get_attr(struct kvm_device *dev,
>         case KVM_DEV_LOONGARCH_IPI_GRP_REGS:
>                 return kvm_ipi_regs_access(dev, attr, false);
>         default:
> -               kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
> +               WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
>                 return -EINVAL;
>         }
>  }
> @@ -381,7 +381,7 @@ static int kvm_ipi_set_attr(struct kvm_device *dev,
>         case KVM_DEV_LOONGARCH_IPI_GRP_REGS:
>                 return kvm_ipi_regs_access(dev, attr, true);
>         default:
> -               kvm_err("%s: unknown group (%d)\n", __func__, attr->group);
> +               WARN_ONCE(1, "%s: unknown group (%d)\n", __func__, attr->group);
>                 return -EINVAL;
>         }
>  }
> @@ -394,13 +394,13 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)
>         struct loongarch_ipi *s;
>
>         if (!dev) {
> -               kvm_err("%s: kvm_device ptr is invalid!\n", __func__);
> +               WARN_ONCE(1, "%s: kvm_device ptr is invalid!\n", __func__);
>                 return -EINVAL;
>         }
>
>         kvm = dev->kvm;
>         if (kvm->arch.ipi) {
> -               kvm_err("%s: LoongArch IPI has already been created!\n", __func__);
> +               WARN_ONCE(1, "%s: LoongArch IPI has already been created!\n", __func__);
>                 return -EINVAL;
>         }
>
> @@ -420,7 +420,7 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)
>         ret = kvm_io_bus_register_dev(kvm, KVM_IOCSR_BUS, IOCSR_IPI_BASE, IOCSR_IPI_SIZE, device);
>         mutex_unlock(&kvm->slots_lock);
>         if (ret < 0) {
> -               kvm_err("%s: Initialize IOCSR dev failed, ret = %d\n", __func__, ret);
> +               WARN_ONCE(1, "%s: Initialize IOCSR dev failed, ret = %d\n", __func__, ret);
>                 goto err;
>         }
>
> diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
> index 175a630aceb4..299b4db26833 100644
> --- a/arch/loongarch/kvm/intc/pch_pic.c
> +++ b/arch/loongarch/kvm/intc/pch_pic.c
> @@ -151,12 +151,12 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
>         struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;
>
>         if (!s) {
> -               kvm_err("%s: pch pic irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: pch pic irqchip not valid!\n", __func__);
>                 return ret;
>         }
>
>         if (addr & (len - 1)) {
> -               kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
> +               WARN_ONCE(1, "%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
>                 return ret;
>         }
>
> @@ -250,12 +250,12 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
>         struct loongarch_pch_pic *s = vcpu->kvm->arch.pch_pic;
>
>         if (!s) {
> -               kvm_err("%s: pch pic irqchip not valid!\n", __func__);
> +               WARN_ONCE(1, "%s: pch pic irqchip not valid!\n", __func__);
>                 return ret;
>         }
>
>         if (addr & (len - 1)) {
> -               kvm_err("%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
> +               WARN_ONCE(1, "%s: pch pic not aligned addr %llx len %d\n", __func__, addr, len);
>                 return ret;
>         }
>
> @@ -390,13 +390,13 @@ static int kvm_pch_pic_set_attr(struct kvm_device *dev,
>                                 return -EFAULT;
>
>                         if (!dev->kvm->arch.pch_pic) {
> -                               kvm_err("%s: please create pch_pic irqchip first!\n", __func__);
> +                               WARN_ONCE(1, "%s: please create pch_pic irqchip first\n", __func__);
>                                 return -ENODEV;
>                         }
>
>                         return kvm_pch_pic_init(dev, addr);
>                 default:
> -                       kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
> +                       WARN_ONCE(1, "%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
>                                         attr->attr);
>                         return -EINVAL;
>                 }
> diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
> index 20c207d80e31..361fca46e2b3 100644
> --- a/arch/loongarch/kvm/vcpu.c
> +++ b/arch/loongarch/kvm/vcpu.c
> @@ -1473,7 +1473,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)
>         else if (intr < 0)
>                 kvm_dequeue_irq(vcpu, -intr);
>         else {
> -               kvm_err("%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
> +               WARN_ONCE(1, "%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
>                 return -EINVAL;
>         }
>
> --
> 2.39.3
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-06-30  4:27 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-29  2:32 [PATCH v3 0/3] LoongArch: KVM: Harden interrupt injection Bibo Mao
2026-06-29  2:32 ` [PATCH v3 1/3] LoongArch: KVM: Set default MAILBOX access size with 8 Bibo Mao
2026-06-29  2:45   ` sashiko-bot
2026-06-29  2:32 ` [PATCH v3 2/3] LoongArch: KVM: Replace kvm_err() with WARN_ONCE() Bibo Mao
2026-06-29  2:37   ` sashiko-bot
2026-06-30  4:27   ` Huacai Chen
2026-06-29  2:32 ` [PATCH v3 3/3] LoongArch: KVM: Use internal API to deliver interrupt in kernel mode Bibo Mao
2026-06-29  2:41   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox