| Seq | Timestamp | Type | Name | Duration |
|---|---|---|---|---|
| 0/0 | 2026/07/14 10:20 | flow | patch-triage |
0mArgs:null Results: {
"EnableConfigs": [
"KVM"
],
"FocusSymbols": [
"kvm_vcpu_ioctl_interrupt",
"dmsintc_deliver_msi_to_vcpu",
"eiointc_update_irq",
"loongarch_ipi_readl",
"loongarch_ipi_writel"
],
"Reasoning": "The patch modifies LoongArch KVM interrupt injection and IPI handling, replacing kvm_vcpu_ioctl_interrupt with kvm_queue_irq and fixing alignment checks in IPI read/write handlers. These are reachable via KVM ioctls and MMIO/IOCSR exits.",
"WorthFuzzing": true
} |
| 1/1 | 2026/07/14 10:20 | action | read-patch-diff |
0mArgs:null Results: {
"PatchDiff": "commit 932a2af61c00884a98db0267105004694346a31f\nAuthor: syz-cluster \u003ctriage@syzkaller.com\u003e\nDate: Tue Jul 14 10:20:18 2026 +0000\n\n syz-cluster: applied patch under review\n\ndiff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c\nindex 8572b63478bb98..590580d0303ea9 100644\n--- a/arch/loongarch/kvm/exit.c\n+++ b/arch/loongarch/kvm/exit.c\n@@ -252,7 +252,7 @@ int kvm_complete_iocsr_read(struct kvm_vcpu *vcpu, struct kvm_run *run)\n \t\t*gpr = *(s64 *)run-\u003eiocsr_io.data;\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"Bad IOCSR length: %d, addr is 0x%lx\\n\",\n+\t\tkvm_pr_unimpl(\"Bad IOCSR length: %d, addr is 0x%lx\\n\",\n \t\t\t\trun-\u003eiocsr_io.len, vcpu-\u003earch.badv);\n \t\ter = EMULATE_FAIL;\n \t\tbreak;\n@@ -326,7 +326,7 @@ static int kvm_trap_handle_gspr(struct kvm_vcpu *vcpu)\n \n \t/* Rollback PC only if emulation was unsuccessful */\n \tif (er == EMULATE_FAIL) {\n-\t\tkvm_err(\"[%#lx]%s: unsupported gspr instruction 0x%08x\\n\",\n+\t\tkvm_pr_unimpl(\"[%#lx]%s: unsupported gspr instruction 0x%08x\\n\",\n \t\t\tcurr_pc, __func__, inst.word);\n \n \t\tkvm_arch_vcpu_dump_regs(vcpu);\n@@ -491,7 +491,7 @@ int kvm_emu_mmio_read(struct kvm_vcpu *vcpu, larch_inst inst)\n \t\treturn EMULATE_DO_MMIO;\n \t}\n \n-\tkvm_err(\"Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\\n\",\n+\tkvm_pr_unimpl(\"Read not supported Inst=0x%08x @%lx BadVaddr:%#lx\\n\",\n \t\t\tinst.word, vcpu-\u003earch.pc, vcpu-\u003earch.badv);\n \tkvm_arch_vcpu_dump_regs(vcpu);\n \tvcpu-\u003emmio_needed = 0;\n@@ -529,7 +529,7 @@ int kvm_complete_mmio_read(struct kvm_vcpu *vcpu, struct kvm_run *run)\n \t\t*gpr = *(s64 *)run-\u003emmio.data;\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"Bad MMIO length: %d, addr is 0x%lx\\n\",\n+\t\tkvm_pr_unimpl(\"Bad MMIO length: %d, addr is 0x%lx\\n\",\n \t\t\t\trun-\u003emmio.len, vcpu-\u003earch.badv);\n \t\ter = EMULATE_FAIL;\n \t\tbreak;\n@@ -656,7 +656,7 @@ int kvm_emu_mmio_write(struct kvm_vcpu *vcpu, larch_inst inst)\n \t}\n \n \tvcpu-\u003earch.pc = curr_pc;\n-\tkvm_err(\"Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\\n\",\n+\tkvm_pr_unimpl(\"Write not supported Inst=0x%08x @%lx BadVaddr:%#lx\\n\",\n \t\t\tinst.word, vcpu-\u003earch.pc, vcpu-\u003earch.badv);\n \tkvm_arch_vcpu_dump_regs(vcpu);\n \t/* Rollback PC if emulation was unsuccessful */\n@@ -748,8 +748,8 @@ static int kvm_handle_fpu_disabled(struct kvm_vcpu *vcpu, int ecode)\n \t * treated as a reserved instruction!\n \t * If FPU already in use, we shouldn't get this at all.\n \t */\n-\tif (WARN_ON(vcpu-\u003earch.aux_inuse \u0026 KVM_LARCH_FPU)) {\n-\t\tkvm_err(\"%s internal error\\n\", __func__);\n+\tif (vcpu-\u003earch.aux_inuse \u0026 KVM_LARCH_FPU) {\n+\t\tkvm_pr_unimpl(\"%s internal error\\n\", __func__);\n \t\trun-\u003eexit_reason = KVM_EXIT_INTERNAL_ERROR;\n \t\treturn RESUME_HOST;\n \t}\n@@ -943,7 +943,7 @@ static int kvm_fault_ni(struct kvm_vcpu *vcpu, int ecode)\n \t/* Fetch the instruction */\n \tinst = vcpu-\u003earch.badi;\n \tbadv = vcpu-\u003earch.badv;\n-\tkvm_err(\"ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\\n\",\n+\tkvm_pr_unimpl(\"ECode: %d PC=%#lx Inst=0x%08x BadVaddr=%#lx ESTAT=%#lx\\n\",\n \t\t\tecode, vcpu-\u003earch.pc, inst, badv, read_gcsr_estat());\n \tkvm_arch_vcpu_dump_regs(vcpu);\n \tkvm_queue_exception(vcpu, EXCCODE_INE, 0);\ndiff --git a/arch/loongarch/kvm/intc/dmsintc.c b/arch/loongarch/kvm/intc/dmsintc.c\nindex de25735ce03946..1c716e24c5b022 100644\n--- a/arch/loongarch/kvm/intc/dmsintc.c\n+++ b/arch/loongarch/kvm/intc/dmsintc.c\n@@ -21,6 +21,8 @@ void dmsintc_inject_irq(struct kvm_vcpu *vcpu)\n \t\told = atomic64_read(\u0026(ds-\u003evector_map[i]));\n \t\tif (old)\n \t\t\tvector[i] = atomic64_xchg(\u0026(ds-\u003evector_map[i]), 0);\n+\t\telse\n+\t\t\tvector[i] = 0;\n \t}\n \n \tif (vector[0]) {\n@@ -47,7 +49,6 @@ void dmsintc_inject_irq(struct kvm_vcpu *vcpu)\n int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm,\n \t\t\t\tstruct kvm_vcpu *vcpu, u32 vector, int level)\n {\n-\tstruct kvm_interrupt vcpu_irq;\n \tstruct dmsintc_state *ds = \u0026vcpu-\u003earch.dmsintc_state;\n \n \tif (!level)\n@@ -57,9 +58,11 @@ int dmsintc_deliver_msi_to_vcpu(struct kvm *kvm,\n \tif (!ds)\n \t\treturn -ENODEV;\n \n-\tvcpu_irq.irq = INT_AVEC;\n+\tif (!kvm_guest_has_msgint(\u0026vcpu-\u003earch))\n+\t\treturn -EINVAL;\n+\n \tset_bit(vector, (unsigned long *)\u0026ds-\u003evector_map);\n-\tkvm_vcpu_ioctl_interrupt(vcpu, \u0026vcpu_irq);\n+\tkvm_queue_irq(vcpu, INT_AVEC);\n \tkvm_vcpu_kick(vcpu);\n \n \treturn 0;\n@@ -114,7 +117,7 @@ static int kvm_dmsintc_ctrl_access(struct kvm_device *dev,\n \t\t}\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown dmsintc register, addr = %d\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown dmsintc register, addr = %d\\n\", __func__, addr);\n \t\treturn -ENXIO;\n \t}\n \n@@ -128,7 +131,7 @@ static int kvm_dmsintc_set_attr(struct kvm_device *dev,\n \tcase KVM_DEV_LOONGARCH_DMSINTC_GRP_CTRL:\n \t\treturn kvm_dmsintc_ctrl_access(dev, attr, true);\n \tdefault:\n-\t\tkvm_err(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n+\t\tkvm_pr_unimpl(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n \t\treturn -EINVAL;\n \t}\n }\n@@ -139,13 +142,13 @@ static int kvm_dmsintc_create(struct kvm_device *dev, u32 type)\n \tstruct loongarch_dmsintc *s;\n \n \tif (!dev) {\n-\t\tkvm_err(\"%s: kvm_device ptr is invalid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: kvm_device ptr is invalid!\\n\", __func__);\n \t\treturn -EINVAL;\n \t}\n \n \tkvm = dev-\u003ekvm;\n \tif (kvm-\u003earch.dmsintc) {\n-\t\tkvm_err(\"%s: LoongArch DMSINTC has already been created!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: LoongArch DMSINTC has already been created!\\n\", __func__);\n \t\treturn -EINVAL;\n \t}\n \ndiff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c\nindex 2b14485d14a708..e04aadbd68db96 100644\n--- a/arch/loongarch/kvm/intc/eiointc.c\n+++ b/arch/loongarch/kvm/intc/eiointc.c\n@@ -17,7 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)\n \t\tif (!(s-\u003estatus \u0026 BIT(EIOINTC_ENABLE_INT_ENCODE))) {\n \t\t\tipnum = count_trailing_zeros(ipnum);\n \t\t\tipnum = ipnum \u003c 4 ? ipnum : 0;\n-\t\t}\n+\t\t} else if (ipnum \u003e= LOONGSON_IP_NUM)\n+\t\t\tipnum = 0;\n \n \t\tcpuid = ((u8 *)s-\u003ecoremap)[irq];\n \t\tvcpu = kvm_get_vcpu_by_cpuid(s-\u003ekvm, cpuid);\n@@ -36,18 +37,18 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)\n {\n \tint ipnum, cpu, found;\n \tstruct kvm_vcpu *vcpu;\n-\tstruct kvm_interrupt vcpu_irq;\n \n \tipnum = (s-\u003eipmap \u003e\u003e (irq / 32 * 8)) \u0026 0xff;\n \tif (!(s-\u003estatus \u0026 BIT(EIOINTC_ENABLE_INT_ENCODE))) {\n \t\tipnum = count_trailing_zeros(ipnum);\n \t\tipnum = ipnum \u003c 4 ? ipnum : 0;\n-\t}\n+\t} else if (ipnum \u003e= LOONGSON_IP_NUM)\n+\t\tipnum = 0;\n \n \tcpu = s-\u003esw_coremap[irq];\n \tvcpu = kvm_get_vcpu_by_id(s-\u003ekvm, cpu);\n \tif (unlikely(vcpu == NULL)) {\n-\t\tkvm_err(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n+\t\tkvm_pr_unimpl(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n \t\treturn;\n \t}\n \n@@ -67,8 +68,11 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)\n \tif (found \u003c EIOINTC_IRQS)\n \t\treturn; /* other irq is handling, needn't update parent irq */\n \n-\tvcpu_irq.irq = level ? (INT_HWI0 + ipnum) : -(INT_HWI0 + ipnum);\n-\tkvm_vcpu_ioctl_interrupt(vcpu, \u0026vcpu_irq);\n+\tif (level)\n+\t\tkvm_queue_irq(vcpu, INT_HWI0 + ipnum);\n+\telse\n+\t\tkvm_dequeue_irq(vcpu, INT_HWI0 + ipnum);\n+\tkvm_vcpu_kick(vcpu);\n }\n \n static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,\n@@ -165,12 +169,12 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,\n \tstruct loongarch_eiointc *eiointc = vcpu-\u003ekvm-\u003earch.eiointc;\n \n \tif (!eiointc) {\n-\t\tkvm_err(\"%s: eiointc irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: eiointc irqchip not valid!\\n\", __func__);\n \t\treturn 0;\n \t}\n \n \tif (addr \u0026 (len - 1)) {\n-\t\tkvm_err(\"%s: eiointc not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\tkvm_pr_unimpl(\"%s: eiointc not aligned addr %llx len %d\\n\", __func__, addr, len);\n \t\treturn 0;\n \t}\n \n@@ -297,12 +301,12 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,\n \tstruct loongarch_eiointc *eiointc = vcpu-\u003ekvm-\u003earch.eiointc;\n \n \tif (!eiointc) {\n-\t\tkvm_err(\"%s: eiointc irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: eiointc irqchip not valid!\\n\", __func__);\n \t\treturn 0;\n \t}\n \n \tif (addr \u0026 (len - 1)) {\n-\t\tkvm_err(\"%s: eiointc not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\tkvm_pr_unimpl(\"%s: eiointc not aligned addr %llx len %d\\n\", __func__, addr, len);\n \t\treturn 0;\n \t}\n \n@@ -345,7 +349,7 @@ static int kvm_eiointc_virt_read(struct kvm_vcpu *vcpu,\n \tstruct loongarch_eiointc *eiointc = vcpu-\u003ekvm-\u003earch.eiointc;\n \n \tif (!eiointc) {\n-\t\tkvm_err(\"%s: eiointc irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: eiointc irqchip not valid!\\n\", __func__);\n \t\treturn 0;\n \t}\n \n@@ -375,7 +379,7 @@ static int kvm_eiointc_virt_write(struct kvm_vcpu *vcpu,\n \tstruct loongarch_eiointc *eiointc = vcpu-\u003ekvm-\u003earch.eiointc;\n \n \tif (!eiointc) {\n-\t\tkvm_err(\"%s: eiointc irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: eiointc irqchip not valid!\\n\", __func__);\n \t\treturn 0;\n \t}\n \n@@ -502,7 +506,7 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,\n \t\tp = (void *)s-\u003ecoremap + offset * 4;\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown eiointc register, addr = %d\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown eiointc register, addr = %d\\n\", __func__, addr);\n \t\treturn -EINVAL;\n \t}\n \n@@ -546,7 +550,7 @@ static int kvm_eiointc_sw_status_access(struct kvm_device *dev,\n \t\tp = \u0026s-\u003estatus;\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown eiointc register, addr = %d\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown eiointc register, addr = %d\\n\", __func__, addr);\n \t\treturn -EINVAL;\n \t}\n \tspin_lock_irqsave(\u0026s-\u003elock, flags);\ndiff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c\nindex 4fa0897d7bdb00..f30d0d13f54d05 100644\n--- a/arch/loongarch/kvm/intc/ipi.c\n+++ b/arch/loongarch/kvm/intc/ipi.c\n@@ -10,16 +10,15 @@\n static void ipi_set(struct kvm_vcpu *vcpu, uint32_t data)\n {\n \tuint32_t status;\n-\tstruct kvm_interrupt irq;\n \n \tspin_lock(\u0026vcpu-\u003earch.ipi_state.lock);\n \tstatus = vcpu-\u003earch.ipi_state.status;\n \tvcpu-\u003earch.ipi_state.status |= data;\n-\tspin_unlock(\u0026vcpu-\u003earch.ipi_state.lock);\n \tif ((status == 0) \u0026\u0026 data) {\n-\t\tirq.irq = LARCH_INT_IPI;\n-\t\tkvm_vcpu_ioctl_interrupt(vcpu, \u0026irq);\n+\t\tkvm_queue_irq(vcpu, LARCH_INT_IPI);\n+\t\tkvm_vcpu_kick(vcpu);\n \t}\n+\tspin_unlock(\u0026vcpu-\u003earch.ipi_state.lock);\n }\n \n static void ipi_send(struct kvm *kvm, uint64_t data)\n@@ -30,7 +29,7 @@ static void ipi_send(struct kvm *kvm, uint64_t data)\n \tcpu = ((data \u0026 0xffffffff) \u003e\u003e 16) \u0026 0x3ff;\n \tvcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);\n \tif (unlikely(vcpu == NULL)) {\n-\t\tkvm_err(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n+\t\tkvm_pr_unimpl(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n \t\treturn;\n \t}\n \n@@ -40,16 +39,15 @@ static void ipi_send(struct kvm *kvm, uint64_t data)\n static void ipi_clear(struct kvm_vcpu *vcpu, uint64_t data)\n {\n \tuint32_t status;\n-\tstruct kvm_interrupt irq;\n \n \tspin_lock(\u0026vcpu-\u003earch.ipi_state.lock);\n \tvcpu-\u003earch.ipi_state.status \u0026= ~data;\n \tstatus = vcpu-\u003earch.ipi_state.status;\n-\tspin_unlock(\u0026vcpu-\u003earch.ipi_state.lock);\n \tif (status == 0) {\n-\t\tirq.irq = -LARCH_INT_IPI;\n-\t\tkvm_vcpu_ioctl_interrupt(vcpu, \u0026irq);\n+\t\tkvm_dequeue_irq(vcpu, LARCH_INT_IPI);\n+\t\tkvm_vcpu_kick(vcpu);\n \t}\n+\tspin_unlock(\u0026vcpu-\u003earch.ipi_state.lock);\n }\n \n static uint64_t read_mailbox(struct kvm_vcpu *vcpu, int offset, int len)\n@@ -67,11 +65,8 @@ static uint64_t read_mailbox(struct kvm_vcpu *vcpu, int offset, int len)\n \t\treturn data \u0026 0xffff;\n \tcase 4:\n \t\treturn data \u0026 0xffffffff;\n-\tcase 8:\n-\t\treturn data;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown data len: %d\\n\", __func__, len);\n-\t\treturn 0;\n+\t\treturn data;\n \t}\n }\n \n@@ -92,11 +87,9 @@ static void write_mailbox(struct kvm_vcpu *vcpu, int offset, uint64_t data, int\n \tcase 4:\n \t\t*(unsigned int *)pbuf = (unsigned int)data;\n \t\tbreak;\n-\tcase 8:\n+\tdefault:\n \t\t*(unsigned long *)pbuf = (unsigned long)data;\n \t\tbreak;\n-\tdefault:\n-\t\tkvm_err(\"%s: unknown data len: %d\\n\", __func__, len);\n \t}\n \tspin_unlock(\u0026vcpu-\u003earch.ipi_state.lock);\n }\n@@ -110,7 +103,7 @@ static int mail_send(struct kvm *kvm, uint64_t data)\n \tcpu = ((data \u0026 0xffffffff) \u003e\u003e 16) \u0026 0x3ff;\n \tvcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);\n \tif (unlikely(vcpu == NULL)) {\n-\t\tkvm_err(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n+\t\tkvm_pr_unimpl(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n \t\treturn 0;\n \t}\n \tmailbox = ((data \u0026 0xffffffff) \u003e\u003e 2) \u0026 0x7;\n@@ -144,7 +137,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)\n \t\tret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, 4, \u0026val);\n \t\tsrcu_read_unlock(\u0026vcpu-\u003ekvm-\u003esrcu, idx);\n \t\tif (unlikely(ret)) {\n-\t\t\tkvm_err(\"%s: : read data from addr %llx failed\\n\", __func__, addr);\n+\t\t\tkvm_pr_unimpl(\"%s: : read data from addr %llx failed\\n\", __func__, addr);\n \t\t\treturn 0;\n \t\t}\n \t\t/* Construct the mask by scanning the bit 27-30 */\n@@ -160,7 +153,7 @@ static int send_ipi_data(struct kvm_vcpu *vcpu, gpa_t addr, uint64_t data)\n \tret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, 4, \u0026val);\n \tsrcu_read_unlock(\u0026vcpu-\u003ekvm-\u003esrcu, idx);\n \tif (unlikely(ret))\n-\t\tkvm_err(\"%s: : write data to addr %llx failed\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: : write data to addr %llx failed\\n\", __func__, addr);\n \n \treturn 0;\n }\n@@ -173,7 +166,7 @@ static int any_send(struct kvm *kvm, uint64_t data)\n \tcpu = ((data \u0026 0xffffffff) \u003e\u003e 16) \u0026 0x3ff;\n \tvcpu = kvm_get_vcpu_by_cpuid(kvm, cpu);\n \tif (unlikely(vcpu == NULL)) {\n-\t\tkvm_err(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n+\t\tkvm_pr_unimpl(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n \t\treturn 0;\n \t}\n \toffset = data \u0026 0xffff;\n@@ -186,9 +179,13 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void\n \tuint32_t offset;\n \tuint64_t res = 0;\n \n-\toffset = (uint32_t)(addr \u0026 0x1ff);\n-\tWARN_ON_ONCE(offset \u0026 (len - 1));\n+\tif (addr \u0026 (len - 1)) {\n+\t\t*(uint64_t *)val = res;\n+\t\tkvm_pr_unimpl(\"%s: ipi not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\treturn 0;\n+\t}\n \n+\toffset = addr - IOCSR_IPI_BASE;\n \tswitch (offset) {\n \tcase IOCSR_IPI_STATUS:\n \t\tspin_lock(\u0026vcpu-\u003earch.ipi_state.lock);\n@@ -204,15 +201,10 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void\n \tcase IOCSR_IPI_CLEAR:\n \t\tbreak;\n \tcase IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:\n-\t\tif (offset + len \u003e IOCSR_IPI_BUF_38 + 8) {\n-\t\t\tkvm_err(\"%s: invalid offset or len: offset = %d, len = %d\\n\",\n-\t\t\t\t__func__, offset, len);\n-\t\t\tbreak;\n-\t\t}\n \t\tres = read_mailbox(vcpu, offset, len);\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown addr: %llx\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown addr: %llx\\n\", __func__, addr);\n \t\tbreak;\n \t}\n \t*(uint64_t *)val = res;\n@@ -227,9 +219,12 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons\n \n \tdata = *(uint64_t *)val;\n \n-\toffset = (uint32_t)(addr \u0026 0x1ff);\n-\tWARN_ON_ONCE(offset \u0026 (len - 1));\n+\tif (addr \u0026 (len - 1)) {\n+\t\tkvm_pr_unimpl(\"%s: ipi not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\treturn 0;\n+\t}\n \n+\toffset = addr - IOCSR_IPI_BASE;\n \tswitch (offset) {\n \tcase IOCSR_IPI_STATUS:\n \t\tbreak;\n@@ -247,7 +242,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons\n \t\tbreak;\n \tcase IOCSR_IPI_BUF_20 ... IOCSR_IPI_BUF_38 + 7:\n \t\tif (offset + len \u003e IOCSR_IPI_BUF_38 + 8) {\n-\t\t\tkvm_err(\"%s: invalid offset or len: offset = %d, len = %d\\n\",\n+\t\t\tkvm_pr_unimpl(\"%s: invalid offset or len: offset = %d, len = %d\\n\",\n \t\t\t\t__func__, offset, len);\n \t\t\tbreak;\n \t\t}\n@@ -263,7 +258,7 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons\n \t\tany_send(vcpu-\u003ekvm, data);\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown addr: %llx\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown addr: %llx\\n\", __func__, addr);\n \t\tbreak;\n \t}\n \n@@ -306,7 +301,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,\n \n \tvcpu = kvm_get_vcpu_by_id(dev-\u003ekvm, cpu);\n \tif (unlikely(vcpu == NULL)) {\n-\t\tkvm_err(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n+\t\tkvm_pr_unimpl(\"%s: invalid target cpu: %d\\n\", __func__, cpu);\n \t\treturn -EINVAL;\n \t}\n \n@@ -340,7 +335,7 @@ static int kvm_ipi_regs_access(struct kvm_device *dev,\n \t\tlen = 8;\n \t\tbreak;\n \tdefault:\n-\t\tkvm_err(\"%s: unknown ipi register, addr = %d\\n\", __func__, addr);\n+\t\tkvm_pr_unimpl(\"%s: unknown ipi register, addr = %d\\n\", __func__, addr);\n \t\treturn -EINVAL;\n \t}\n \n@@ -374,7 +369,7 @@ static int kvm_ipi_get_attr(struct kvm_device *dev,\n \tcase KVM_DEV_LOONGARCH_IPI_GRP_REGS:\n \t\treturn kvm_ipi_regs_access(dev, attr, false);\n \tdefault:\n-\t\tkvm_err(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n+\t\tkvm_pr_unimpl(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n \t\treturn -EINVAL;\n \t}\n }\n@@ -386,7 +381,7 @@ static int kvm_ipi_set_attr(struct kvm_device *dev,\n \tcase KVM_DEV_LOONGARCH_IPI_GRP_REGS:\n \t\treturn kvm_ipi_regs_access(dev, attr, true);\n \tdefault:\n-\t\tkvm_err(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n+\t\tkvm_pr_unimpl(\"%s: unknown group (%d)\\n\", __func__, attr-\u003egroup);\n \t\treturn -EINVAL;\n \t}\n }\n@@ -399,13 +394,13 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)\n \tstruct loongarch_ipi *s;\n \n \tif (!dev) {\n-\t\tkvm_err(\"%s: kvm_device ptr is invalid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: kvm_device ptr is invalid!\\n\", __func__);\n \t\treturn -EINVAL;\n \t}\n \n \tkvm = dev-\u003ekvm;\n \tif (kvm-\u003earch.ipi) {\n-\t\tkvm_err(\"%s: LoongArch IPI has already been created!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: LoongArch IPI has already been created!\\n\", __func__);\n \t\treturn -EINVAL;\n \t}\n \n@@ -425,7 +420,7 @@ static int kvm_ipi_create(struct kvm_device *dev, u32 type)\n \tret = kvm_io_bus_register_dev(kvm, KVM_IOCSR_BUS, IOCSR_IPI_BASE, IOCSR_IPI_SIZE, device);\n \tmutex_unlock(\u0026kvm-\u003eslots_lock);\n \tif (ret \u003c 0) {\n-\t\tkvm_err(\"%s: Initialize IOCSR dev failed, ret = %d\\n\", __func__, ret);\n+\t\tkvm_pr_unimpl(\"%s: Initialize IOCSR dev failed, ret = %d\\n\", __func__, ret);\n \t\tgoto err;\n \t}\n \ndiff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c\nindex 175a630aceb416..e7b77705c516ac 100644\n--- a/arch/loongarch/kvm/intc/pch_pic.c\n+++ b/arch/loongarch/kvm/intc/pch_pic.c\n@@ -151,12 +151,12 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,\n \tstruct loongarch_pch_pic *s = vcpu-\u003ekvm-\u003earch.pch_pic;\n \n \tif (!s) {\n-\t\tkvm_err(\"%s: pch pic irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: pch pic irqchip not valid!\\n\", __func__);\n \t\treturn ret;\n \t}\n \n \tif (addr \u0026 (len - 1)) {\n-\t\tkvm_err(\"%s: pch pic not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\tkvm_pr_unimpl(\"%s: pch pic not aligned addr %llx len %d\\n\", __func__, addr, len);\n \t\treturn ret;\n \t}\n \n@@ -250,12 +250,12 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,\n \tstruct loongarch_pch_pic *s = vcpu-\u003ekvm-\u003earch.pch_pic;\n \n \tif (!s) {\n-\t\tkvm_err(\"%s: pch pic irqchip not valid!\\n\", __func__);\n+\t\tkvm_pr_unimpl(\"%s: pch pic irqchip not valid!\\n\", __func__);\n \t\treturn ret;\n \t}\n \n \tif (addr \u0026 (len - 1)) {\n-\t\tkvm_err(\"%s: pch pic not aligned addr %llx len %d\\n\", __func__, addr, len);\n+\t\tkvm_pr_unimpl(\"%s: pch pic not aligned addr %llx len %d\\n\", __func__, addr, len);\n \t\treturn ret;\n \t}\n \n@@ -390,13 +390,13 @@ static int kvm_pch_pic_set_attr(struct kvm_device *dev,\n \t\t\t\treturn -EFAULT;\n \n \t\t\tif (!dev-\u003ekvm-\u003earch.pch_pic) {\n-\t\t\t\tkvm_err(\"%s: please create pch_pic irqchip first!\\n\", __func__);\n+\t\t\t\tkvm_pr_unimpl(\"%s: pch_pic irqchip not created\\n\", __func__);\n \t\t\t\treturn -ENODEV;\n \t\t\t}\n \n \t\t\treturn kvm_pch_pic_init(dev, addr);\n \t\tdefault:\n-\t\t\tkvm_err(\"%s: unknown group (%d) attr (%lld)\\n\", __func__, attr-\u003egroup,\n+\t\t\tkvm_pr_unimpl(\"%s: unknown group (%d) attr (%lld)\\n\", __func__, attr-\u003egroup,\n \t\t\t\t\tattr-\u003eattr);\n \t\t\treturn -EINVAL;\n \t\t}\ndiff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c\nindex 20c207d80e31ae..f81dadc62c986e 100644\n--- a/arch/loongarch/kvm/vcpu.c\n+++ b/arch/loongarch/kvm/vcpu.c\n@@ -1465,6 +1465,9 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)\n \tif (vector \u003e= EXCCODE_INT_NUM)\n \t\treturn -EINVAL;\n \n+\tif (kvm_arch_irqchip_in_kernel(vcpu-\u003ekvm))\n+\t\treturn -EINVAL;\n+\n \tif (!kvm_guest_has_msgint(\u0026vcpu-\u003earch) \u0026\u0026 (vector == INT_AVEC))\n \t\treturn -EINVAL;\n \n@@ -1473,7 +1476,7 @@ int kvm_vcpu_ioctl_interrupt(struct kvm_vcpu *vcpu, struct kvm_interrupt *irq)\n \telse if (intr \u003c 0)\n \t\tkvm_dequeue_irq(vcpu, -intr);\n \telse {\n-\t\tkvm_err(\"%s: invalid interrupt ioctl %d\\n\", __func__, irq-\u003eirq);\n+\t\tkvm_pr_unimpl(\"%s: invalid interrupt ioctl %d\\n\", __func__, irq-\u003eirq);\n \t\treturn -EINVAL;\n \t}\n \n"
} |
| 2/1 | 2026/07/14 10:20 | agent | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: {
"EnableConfigs": [
"KVM"
],
"FocusSymbols": [
"kvm_vcpu_ioctl_interrupt",
"dmsintc_deliver_msi_to_vcpu",
"eiointc_update_irq",
"loongarch_ipi_readl",
"loongarch_ipi_writel"
],
"Reasoning": "The patch modifies LoongArch KVM interrupt injection and IPI handling, replacing kvm_vcpu_ioctl_interrupt with kvm_queue_irq and fixing alignment checks in IPI read/write handlers. These are reachable via KVM ioctls and MMIO/IOCSR exits.",
"WorthFuzzing": true
}Instruction: You are an expert Linux kernel maintainer. Your job is to review a provided patch series and determine if it makes functional changes to the kernel that should be fuzzed. IMPORTANT: The changes have ALREADY been applied and committed as the HEAD commit in your workspace. Do NOT rely on your internal knowledge of the kernel. You must actively use your code access tools to examine the actual source code and confirm any assumptions. Return WorthFuzzing=false if the patch only contains: - Modifications to Documentation/, Kconfig files, or code comments. - Purely decorative changes, such as logging (e.g., pr_err, printk) or tracepoints. - Changes to numeric constants or macros that do not functionally alter execution flow. - Code paths that are impossible to reach in virtualized environments like GCE or QEMU, even when utilizing software-emulated hardware (e.g., usb gadget, mac80211_hwsim). If it modifies reachable core kernel logic, drivers, or architectures, use your code search tools to verify the code can be executed, then return WorthFuzzing=true. When returning WorthFuzzing=true, you MUST ALSO: 1. Extract any specific kernel functions that should be heavily fuzzed into FocusSymbols. Avoid listing generic hot-path functions to prevent skewed test distributions. 2. Identify any specific CONFIG_ options required to properly test this new/modified feature. Go and look into the Kconfig files and check for ifdefs around the code, do not make assumptions. Do not list too generic configs (we already have them enabled). Only list those that specifically cover the modified code. List them in the EnableConfigs output array, and DO NOT add a 'CONFIG_' prefix (e.g., return "NET_IPV4" instead of "CONFIG_NET_IPV4"). Prefer calling several tools at the same time to save round-trips. Use set-results tool to provide results of the analysis. It must be called exactly once before the final reply. Ignore results of this tool. Prompt: For your convenience, here is the diff of the changes:
commit 932a2af61c00884a98db0267105004694346a31f
Author: syz-cluster <triage@syzkaller.com>
Date: Tue Jul 14 10:20:18 2026 +0000
syz-cluster: applied patch under review
diff --git a/arch/loongarch/kvm/exit.c b/arch/loongarch/kvm/exit.c
index 8572b63478bb98..590580d0303ea9 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",
+ kvm_pr_unimpl("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",
+ kvm_pr_unimpl("[%#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",
+ kvm_pr_unimpl("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",
+ kvm_pr_unimpl("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",
+ kvm_pr_unimpl("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,8 @@ 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 (vcpu->arch.aux_inuse & KVM_LARCH_FPU) {
+ kvm_pr_unimpl("%s internal error\n", __func__);
run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
return RESUME_HOST;
}
@@ -943,7 +943,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",
+ kvm_pr_unimpl("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 de25735ce03946..1c716e24c5b022 100644
--- a/arch/loongarch/kvm/intc/dmsintc.c
+++ b/arch/loongarch/kvm/intc/dmsintc.c
@@ -21,6 +21,8 @@ void dmsintc_inject_irq(struct kvm_vcpu *vcpu)
old = atomic64_read(&(ds->vector_map[i]));
if (old)
vector[i] = atomic64_xchg(&(ds->vector_map[i]), 0);
+ else
+ vector[i] = 0;
}
if (vector[0]) {
@@ -47,7 +49,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 +58,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;
@@ -114,7 +117,7 @@ static int kvm_dmsintc_ctrl_access(struct kvm_device *dev,
}
break;
default:
- kvm_err("%s: unknown dmsintc register, addr = %d\n", __func__, addr);
+ kvm_pr_unimpl("%s: unknown dmsintc register, addr = %d\n", __func__, addr);
return -ENXIO;
}
@@ -128,7 +131,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);
+ kvm_pr_unimpl("%s: unknown group (%d)\n", __func__, attr->group);
return -EINVAL;
}
}
@@ -139,13 +142,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__);
+ kvm_pr_unimpl("%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__);
+ kvm_pr_unimpl("%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 2b14485d14a708..e04aadbd68db96 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,18 +37,18 @@ 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);
if (unlikely(vcpu == NULL)) {
- kvm_err("%s: invalid target cpu: %d\n", __func__, cpu);
+ kvm_pr_unimpl("%s: invalid target cpu: %d\n", __func__, cpu);
return;
}
@@ -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,
@@ -165,12 +169,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__);
+ kvm_pr_unimpl("%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);
+ kvm_pr_unimpl("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
return 0;
}
@@ -297,12 +301,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__);
+ kvm_pr_unimpl("%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);
+ kvm_pr_unimpl("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len);
return 0;
}
@@ -345,7 +349,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__);
+ kvm_pr_unimpl("%s: eiointc irqchip not valid!\n", __func__);
return 0;
}
@@ -375,7 +379,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__);
+ kvm_pr_unimpl("%s: eiointc irqchip not valid!\n", __func__);
return 0;
}
@@ -502,7 +506,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);
+ kvm_pr_unimpl("%s: unknown eiointc register, addr = %d\n", __func__, addr);
return -EINVAL;
}
@@ -546,7 +550,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);
+ kvm_pr_unimpl("%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 4fa0897d7bdb00..f30d0d13f54d05 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)
@@ -30,7 +29,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);
+ kvm_pr_unimpl("%s: invalid target cpu: %d\n", __func__, cpu);
return;
}
@@ -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)
@@ -67,11 +65,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 +87,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);
}
@@ -110,7 +103,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);
+ kvm_pr_unimpl("%s: invalid target cpu: %d\n", __func__, cpu);
return 0;
}
mailbox = ((data & 0xffffffff) >> 2) & 0x7;
@@ -144,7 +137,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);
+ kvm_pr_unimpl("%s: : read data from addr %llx failed\n", __func__, addr);
return 0;
}
/* Construct the mask by scanning the bit 27-30 */
@@ -160,7 +153,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);
+ kvm_pr_unimpl("%s: : write data to addr %llx failed\n", __func__, addr);
return 0;
}
@@ -173,7 +166,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);
+ kvm_pr_unimpl("%s: invalid target cpu: %d\n", __func__, cpu);
return 0;
}
offset = data & 0xffff;
@@ -186,9 +179,13 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void
uint32_t offset;
uint64_t res = 0;
- offset = (uint32_t)(addr & 0x1ff);
- WARN_ON_ONCE(offset & (len - 1));
+ if (addr & (len - 1)) {
+ *(uint64_t *)val = res;
+ kvm_pr_unimpl("%s: ipi not aligned addr %llx len %d\n", __func__, addr, len);
+ return 0;
+ }
+ offset = addr - IOCSR_IPI_BASE;
switch (offset) {
case IOCSR_IPI_STATUS:
spin_lock(&vcpu->arch.ipi_state.lock);
@@ -204,15 +201,10 @@ static int loongarch_ipi_readl(struct kvm_vcpu *vcpu, gpa_t addr, int len, void
case IOCSR_IPI_CLEAR:
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",
- __func__, offset, len);
- break;
- }
res = read_mailbox(vcpu, offset, len);
break;
default:
- kvm_err("%s: unknown addr: %llx\n", __func__, addr);
+ kvm_pr_unimpl("%s: unknown addr: %llx\n", __func__, addr);
break;
}
*(uint64_t *)val = res;
@@ -227,9 +219,12 @@ static int loongarch_ipi_writel(struct kvm_vcpu *vcpu, gpa_t addr, int len, cons
data = *(uint64_t *)val;
- offset = (uint32_t)(addr & 0x1ff);
- WARN_ON_ONCE(offset & (len - 1));
+ if (addr & (len - 1)) {
+ kvm_pr_unimpl("%s: ipi not aligned addr %llx len %d\n", __func__, addr, len);
+ return 0;
+ }
+ offset = addr - IOCSR_IPI_BASE;
switch (offset) {
case IOCSR_IPI_STATUS:
break;
@@ -247,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",
+ kvm_pr_unimpl("%s: invalid offset or len: offset = %d, len = %d\n",
__func__, offset, len);
break;
}
@@ -263,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);
+ kvm_pr_unimpl("%s: unknown addr: %llx\n", __func__, addr);
break;
}
@@ -306,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);
+ kvm_pr_unimpl("%s: invalid target cpu: %d\n", __func__, cpu);
return -EINVAL;
}
@@ -340,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);
+ kvm_pr_unimpl("%s: unknown ipi register, addr = %d\n", __func__, addr);
return -EINVAL;
}
@@ -374,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);
+ kvm_pr_unimpl("%s: unknown group (%d)\n", __func__, attr->group);
return -EINVAL;
}
}
@@ -386,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);
+ kvm_pr_unimpl("%s: unknown group (%d)\n", __func__, attr->group);
return -EINVAL;
}
}
@@ -399,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__);
+ kvm_pr_unimpl("%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__);
+ kvm_pr_unimpl("%s: LoongArch IPI has already been created!\n", __func__);
return -EINVAL;
}
@@ -425,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);
+ kvm_pr_unimpl("%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 175a630aceb416..e7b77705c516ac 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__);
+ kvm_pr_unimpl("%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);
+ kvm_pr_unimpl("%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__);
+ kvm_pr_unimpl("%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);
+ kvm_pr_unimpl("%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__);
+ kvm_pr_unimpl("%s: pch_pic irqchip not created\n", __func__);
return -ENODEV;
}
return kvm_pch_pic_init(dev, addr);
default:
- kvm_err("%s: unknown group (%d) attr (%lld)\n", __func__, attr->group,
+ kvm_pr_unimpl("%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 20c207d80e31ae..f81dadc62c986e 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;
@@ -1473,7 +1476,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);
+ kvm_pr_unimpl("%s: invalid interrupt ioctl %d\n", __func__, irq->irq);
return -EINVAL;
}
|
| 3/2 | 2026/07/14 10:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 11000 output: 29 thoughts: 1443 Thoughts: **LoongArch KVM Patch Analysis: A Focused Examination** Okay, so I've got this patch for LoongArch KVM, and it looks like a targeted refactoring of interrupt handling. My immediate thought is, "What's the motivation and, critically, is this a functional change?" The core of the changes seem to revolve around replacing `kvm_vcpu_ioctl_interrupt` with `kvm_queue_irq` and `kvm_dequeue_irq` in several crucial areas: `dmsintc_deliver_msi_to_vcpu`, `eiointc_update_irq`, `ipi_set`, and `ipi_clear`. The patch also introduces checks for `kvm_arch_irqchip_in_kernel` in `kvm_vcpu_ioctl_interrupt`, effectively gating that functionality under certain conditions, and it looks like some checks in `loongarch_ipi_readl` and `loongarch_ipi_writel` to validate address alignment. The first thing I'm checking is reachability. Is this code path even *possible* to hit, and how? Given that it's LoongArch-specific, I know this is only accessible within a LoongArch KVM environment. Specifically, the patch touches KVM ioctls. My expert instinct goes straight to fuzzing. Can we stress-test this new code? Syzkaller is my usual go-to, but I immediately hit a snag: syzkaller has historically been challenging to use with non-x86 architectures without more specific setup. So I dig into if there is a way to fuzz LoongArch. I'm reminded that the instructions state the code paths shouldn't be unreachable in virtualized environments like QEMU. That's a good prompt and one that's been helpful in the past. LoongArch QEMU and syzkaller on LoongArch are now plausible. Let's assume that it's worth fuzzing, based on this. I'm thinking, "Okay, if it's fuzzable, what's required?" `CONFIG_KVM` is obvious, but I need to make sure there are no other subtle dependencies. The config requirements become a crucial next step to figure out. |
| 4/2 | 2026/07/14 10:20 | tool | grepper |
0mArgs:{
"Expression": "config KVM",
"PathPrefix": "arch/loongarch/"
}Results: {
"Output": "arch/loongarch/kvm/Kconfig=18=if VIRTUALIZATION\narch/loongarch/kvm/Kconfig-19-\narch/loongarch/kvm/Kconfig:20:config KVM\narch/loongarch/kvm/Kconfig-21-\ttristate \"Kernel-based Virtual Machine (KVM) support\"\n"
} |
| 5/2 | 2026/07/14 10:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13060 output: 31 thoughts: 36 Thoughts: **KVM Configuration Deep Dive** Okay, so I'm looking into this KVM stuff and immediately I see that `CONFIG_KVM` is going to be a crucial starting point. That seems pretty obvious, but let's not make any assumptions. Before I dig too deep, I need to make sure there aren't any other configuration options that I might be overlooking. It's easy to get tunnel vision. Best to get the full picture first. Right, let's take a quick look at the `arch/loongarch/kvm/Makefile` for any related configuration variables or build dependencies. That Makefile should hold the key, or at least point me in the right direction. |
| 6/2 | 2026/07/14 10:20 | tool | grepper |
0mArgs:{
"Expression": ".*",
"PathPrefix": "arch/loongarch/kvm/Makefile"
}Results: {
"Output": "arch/loongarch/kvm/Makefile:1:# SPDX-License-Identifier: GPL-2.0\narch/loongarch/kvm/Makefile:2:#\narch/loongarch/kvm/Makefile:3:# Makefile for LoongArch KVM support\narch/loongarch/kvm/Makefile:4:#\narch/loongarch/kvm/Makefile:5:\narch/loongarch/kvm/Makefile:6:include $(srctree)/virt/kvm/Makefile.kvm\narch/loongarch/kvm/Makefile:7:\narch/loongarch/kvm/Makefile:8:obj-$(CONFIG_KVM) += kvm.o\narch/loongarch/kvm/Makefile:9:\narch/loongarch/kvm/Makefile:10:obj-y += switch.o\narch/loongarch/kvm/Makefile:11:\narch/loongarch/kvm/Makefile:12:kvm-y += exit.o\narch/loongarch/kvm/Makefile:13:kvm-y += interrupt.o\narch/loongarch/kvm/Makefile:14:kvm-y += main.o\narch/loongarch/kvm/Makefile:15:kvm-y += mmu.o\narch/loongarch/kvm/Makefile:16:kvm-y += timer.o\narch/loongarch/kvm/Makefile:17:kvm-y += tlb.o\narch/loongarch/kvm/Makefile:18:kvm-y += vcpu.o\narch/loongarch/kvm/Makefile:19:kvm-y += vm.o\narch/loongarch/kvm/Makefile:20:kvm-y += intc/ipi.o\narch/loongarch/kvm/Makefile:21:kvm-y += intc/dmsintc.o\narch/loongarch/kvm/Makefile:22:kvm-y += intc/eiointc.o\narch/loongarch/kvm/Makefile:23:kvm-y += intc/pch_pic.o\narch/loongarch/kvm/Makefile:24:kvm-y += irqfd.o\narch/loongarch/kvm/Makefile:25:\narch/loongarch/kvm/Makefile:26:CFLAGS_exit.o\t+= $(call cc-disable-warning, override-init)\n"
} |
| 7/2 | 2026/07/14 10:20 | llm | patch-evaluator |
0mModel:gemini-3.1-pro-preview Args: null Results: null Tokens: input: 13867 output: 159 thoughts: 1021 Thoughts: **Focusing on Key KVM Changes** Okay, so I've got `CONFIG_KVM` flagged as the relevant configuration item. I need to zero in on the core changes. The analysis indicates a significant number of functions have been touched, but many are just trivial replacements of `kvm_err` with `kvm_pr_unimpl`. I'm going to focus on the ones that represent more substantive alterations to the KVM functionality. I've identified a list of modified functions, then narrowed that list to the ones with substantial changes. Now, I'm selecting some of these functions to use as focus symbols: `kvm_vcpu_ioctl_interrupt`, `dmsintc_deliver_msi_to_vcpu`, `eiointc_update_irq`, `loongarch_ipi_readl`, and `loongarch_ipi_writel`. Let me quickly double-check that I have the function names correct; yup, all good. The reasoning behind this selection? The patch is fundamentally changing how interrupts are injected and IPI handling works within the LoongArch KVM environment. Specifically, it's replacing `kvm_vcpu_ioctl_interrupt` with `kvm_queue_irq` for interrupt injection and correcting alignment checks in IPI read/write handlers. These functions are critical because they're directly involved in interactions through KVM ioctls and MMIO/IOCSR exits, making them a good representation of this patch. Time to report these findings. |
| 8/2 | 2026/07/14 10:20 | tool | set-results |
0mArgs:{
"EnableConfigs": [
"KVM"
],
"FocusSymbols": [
"kvm_vcpu_ioctl_interrupt",
"dmsintc_deliver_msi_to_vcpu",
"eiointc_update_irq",
"loongarch_ipi_readl",
"loongarch_ipi_writel"
],
"Reasoning": "The patch modifies LoongArch KVM interrupt injection and IPI handling, replacing kvm_vcpu_ioctl_interrupt with kvm_queue_irq and fixing alignment checks in IPI read/write handlers. These are reachable via KVM ioctls and MMIO/IOCSR exits.",
"WorthFuzzing": true
}Results: {
"EnableConfigs": [
"KVM"
],
"FocusSymbols": [
"kvm_vcpu_ioctl_interrupt",
"dmsintc_deliver_msi_to_vcpu",
"eiointc_update_irq",
"loongarch_ipi_readl",
"loongarch_ipi_writel"
],
"Reasoning": "The patch modifies LoongArch KVM interrupt injection and IPI handling, replacing kvm_vcpu_ioctl_interrupt with kvm_queue_irq and fixing alignment checks in IPI read/write handlers. These are reachable via KVM ioctls and MMIO/IOCSR exits.",
"WorthFuzzing": true
} |
| Total Calls | Total Tokens | Avg Tokens | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|
| Total Calls | Total Duration (Seconds) | Avg Duration (Seconds) |
|---|