linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation
@ 2025-07-09  8:02 Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 1/8] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

This series add generic eiointc 8 bytes access interface, so that 1/2/4/8
bytes access can use the generic 8 bytes access interface. It reduce
about 500 lines redundant code and make eiointc emulation driver
simpler than ever.

---
v5 ... v6:
  1. Merge previous patch 5 & 6 into one, patch 7 & 10 into into one and
     patch 12 and patch 13 into one.
  2. Use sign extension with destination register for IOCSRRD.{B/H/W}
     kernel emulation.

v4 ... v5
  1. Rebase patch on latest kernel where bugfix of eiointc has been
     merged.
  2. Add generic eiointc 8 bytes access interface, 1/2/4/8 bytes access
     uses generic 8 bytes access interface.

v3 ... v4:
  1. Remove patch about enhancement and only keep bugfix relative
     patches.
  2. Remove INTC indication in the patch title.
  3. With access size, keep default case unchanged besides 1/2/4/8 since
     here all patches are bugfix
  4. Firstly check return value of copy_from_user() with error path,
     keep the same order with old patch in patch 4.

v2 ... v3:
  1. Add prefix INTC: in title of every patch.
  2. Fix array index overflow when emulate register EIOINTC_ENABLE
     writing operation.
  3. Add address alignment check with eiointc register access operation.

v1 ... v2:
  1. Add extra fix in patch 3 and patch 4, add num_cpu validation check
  2. Name of stat information keeps unchanged, only move it from VM stat
     to vCPU stat.
---
Bibo Mao (8):
  LoongArch: KVM: Use standard bitops API with eiointc
  LoongArch: KVM: Remove unused parameter len
  LoongArch: KVM: Add stat information with kernel irqchip
  LoongArch: KVM: Remove never called default case statement
  LoongArch: KVM: Use generic function loongarch_eiointc_read()
  LoongArch: KVM: Remove some unnecessary local variables
  LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
  LoongArch: KVM: Add generic function loongarch_eiointc_write()

 arch/loongarch/include/asm/kvm_host.h |  12 +-
 arch/loongarch/kvm/intc/eiointc.c     | 558 ++++----------------------
 arch/loongarch/kvm/intc/ipi.c         |  28 +-
 arch/loongarch/kvm/intc/pch_pic.c     |   4 +-
 arch/loongarch/kvm/vcpu.c             |   8 +-
 5 files changed, 102 insertions(+), 508 deletions(-)


base-commit: 733923397fd95405a48f165c9b1fbc8c4b0a4681
-- 
2.39.3


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

* [PATCH v6 1/8] LoongArch: KVM: Use standard bitops API with eiointc
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 2/8] LoongArch: KVM: Remove unused parameter len Bibo Mao
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Standard bitops APIs such test_bit() is used here, rather than manually
calculate the offset and mask. Also use non-atomic API __set_bit()
and __clear_bit() rather than set_bit() and clear_bit(), since global
spinlock is held already.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 27 +++++++++++----------------
 1 file changed, 11 insertions(+), 16 deletions(-)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index a75f865d6fb9..3cf9894999da 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -9,7 +9,7 @@
 
 static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 {
-	int ipnum, cpu, cpuid, irq_index, irq_mask, irq;
+	int ipnum, cpu, cpuid, irq;
 	struct kvm_vcpu *vcpu;
 
 	for (irq = 0; irq < EIOINTC_IRQS; irq++) {
@@ -18,8 +18,6 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 			ipnum = count_trailing_zeros(ipnum);
 			ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0;
 		}
-		irq_index = irq / 32;
-		irq_mask = BIT(irq & 0x1f);
 
 		cpuid = s->coremap.reg_u8[irq];
 		vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
@@ -27,16 +25,16 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 			continue;
 
 		cpu = vcpu->vcpu_id;
-		if (!!(s->coreisr.reg_u32[cpu][irq_index] & irq_mask))
-			set_bit(irq, s->sw_coreisr[cpu][ipnum]);
+		if (test_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]))
+			__set_bit(irq, s->sw_coreisr[cpu][ipnum]);
 		else
-			clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
+			__clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
 	}
 }
 
 static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 {
-	int ipnum, cpu, found, irq_index, irq_mask;
+	int ipnum, cpu, found;
 	struct kvm_vcpu *vcpu;
 	struct kvm_interrupt vcpu_irq;
 
@@ -48,19 +46,16 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 
 	cpu = s->sw_coremap[irq];
 	vcpu = kvm_get_vcpu(s->kvm, cpu);
-	irq_index = irq / 32;
-	irq_mask = BIT(irq & 0x1f);
-
 	if (level) {
 		/* if not enable return false */
-		if (((s->enable.reg_u32[irq_index]) & irq_mask) == 0)
+		if (!test_bit(irq, (unsigned long *)s->enable.reg_u32))
 			return;
-		s->coreisr.reg_u32[cpu][irq_index] |= irq_mask;
+		__set_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]);
 		found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
-		set_bit(irq, s->sw_coreisr[cpu][ipnum]);
+		__set_bit(irq, s->sw_coreisr[cpu][ipnum]);
 	} else {
-		s->coreisr.reg_u32[cpu][irq_index] &= ~irq_mask;
-		clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
+		__clear_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]);
+		__clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
 		found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
 	}
 
@@ -110,8 +105,8 @@ void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level)
 	unsigned long flags;
 	unsigned long *isr = (unsigned long *)s->isr.reg_u8;
 
-	level ? set_bit(irq, isr) : clear_bit(irq, isr);
 	spin_lock_irqsave(&s->lock, flags);
+	level ? __set_bit(irq, isr) : __clear_bit(irq, isr);
 	eiointc_update_irq(s, irq, level);
 	spin_unlock_irqrestore(&s->lock, flags);
 }
-- 
2.39.3


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

* [PATCH v6 2/8] LoongArch: KVM: Remove unused parameter len
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 1/8] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 3/8] LoongArch: KVM: Add stat information with kernel irqchip Bibo Mao
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Parameter len is unused in some functions with eiointc emulation
driver, remove it here.

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

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 3cf9894999da..acd975ce9608 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -131,7 +131,7 @@ static inline void eiointc_enable_irq(struct kvm_vcpu *vcpu,
 }
 
 static int loongarch_eiointc_readb(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, int len, void *val)
+				gpa_t addr, void *val)
 {
 	int index, ret = 0;
 	u8 data = 0;
@@ -173,7 +173,7 @@ static int loongarch_eiointc_readb(struct kvm_vcpu *vcpu, struct loongarch_eioin
 }
 
 static int loongarch_eiointc_readw(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, int len, void *val)
+				gpa_t addr, void *val)
 {
 	int index, ret = 0;
 	u16 data = 0;
@@ -215,7 +215,7 @@ static int loongarch_eiointc_readw(struct kvm_vcpu *vcpu, struct loongarch_eioin
 }
 
 static int loongarch_eiointc_readl(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, int len, void *val)
+				gpa_t addr, void *val)
 {
 	int index, ret = 0;
 	u32 data = 0;
@@ -257,7 +257,7 @@ static int loongarch_eiointc_readl(struct kvm_vcpu *vcpu, struct loongarch_eioin
 }
 
 static int loongarch_eiointc_readq(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, int len, void *val)
+				gpa_t addr, void *val)
 {
 	int index, ret = 0;
 	u64 data = 0;
@@ -320,16 +320,16 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 	spin_lock_irqsave(&eiointc->lock, flags);
 	switch (len) {
 	case 1:
-		ret = loongarch_eiointc_readb(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_readb(vcpu, eiointc, addr, val);
 		break;
 	case 2:
-		ret = loongarch_eiointc_readw(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_readw(vcpu, eiointc, addr, val);
 		break;
 	case 4:
-		ret = loongarch_eiointc_readl(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
 		break;
 	case 8:
-		ret = loongarch_eiointc_readq(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_readq(vcpu, eiointc, addr, val);
 		break;
 	default:
 		WARN_ONCE(1, "%s: Abnormal address access: addr 0x%llx, size %d\n",
@@ -342,7 +342,7 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 
 static int loongarch_eiointc_writeb(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
-				gpa_t addr, int len, const void *val)
+				gpa_t addr, const void *val)
 {
 	int index, irq, bits, ret = 0;
 	u8 cpu;
@@ -421,7 +421,7 @@ static int loongarch_eiointc_writeb(struct kvm_vcpu *vcpu,
 
 static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
-				gpa_t addr, int len, const void *val)
+				gpa_t addr, const void *val)
 {
 	int i, index, irq, bits, ret = 0;
 	u8 cpu;
@@ -506,7 +506,7 @@ static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu,
 
 static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
-				gpa_t addr, int len, const void *val)
+				gpa_t addr, const void *val)
 {
 	int i, index, irq, bits, ret = 0;
 	u8 cpu;
@@ -591,7 +591,7 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
 
 static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
-				gpa_t addr, int len, const void *val)
+				gpa_t addr, const void *val)
 {
 	int i, index, irq, bits, ret = 0;
 	u8 cpu;
@@ -696,16 +696,16 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 	spin_lock_irqsave(&eiointc->lock, flags);
 	switch (len) {
 	case 1:
-		ret = loongarch_eiointc_writeb(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_writeb(vcpu, eiointc, addr, val);
 		break;
 	case 2:
-		ret = loongarch_eiointc_writew(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_writew(vcpu, eiointc, addr, val);
 		break;
 	case 4:
-		ret = loongarch_eiointc_writel(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_writel(vcpu, eiointc, addr, val);
 		break;
 	case 8:
-		ret = loongarch_eiointc_writeq(vcpu, eiointc, addr, len, val);
+		ret = loongarch_eiointc_writeq(vcpu, eiointc, addr, val);
 		break;
 	default:
 		WARN_ONCE(1, "%s: Abnormal address access: addr 0x%llx, size %d\n",
-- 
2.39.3


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

* [PATCH v6 3/8] LoongArch: KVM: Add stat information with kernel irqchip
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 1/8] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 2/8] LoongArch: KVM: Remove unused parameter len Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 4/8] LoongArch: KVM: Remove never called default case statement Bibo Mao
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Move stat information about kernel irqchip from VM to vCPU, since
all vm exiting events should be vCPU relative. And also add entry
with structure kvm_vcpu_stats_desc[], so that it can display with
directory /sys/kernel/debug/kvm.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/include/asm/kvm_host.h | 12 ++++++------
 arch/loongarch/kvm/intc/eiointc.c     |  4 ++--
 arch/loongarch/kvm/intc/ipi.c         | 28 ++++-----------------------
 arch/loongarch/kvm/intc/pch_pic.c     |  4 ++--
 arch/loongarch/kvm/vcpu.c             |  8 +++++++-
 5 files changed, 21 insertions(+), 35 deletions(-)

diff --git a/arch/loongarch/include/asm/kvm_host.h b/arch/loongarch/include/asm/kvm_host.h
index a3c4cc46c892..0cecbd038bb3 100644
--- a/arch/loongarch/include/asm/kvm_host.h
+++ b/arch/loongarch/include/asm/kvm_host.h
@@ -50,12 +50,6 @@ struct kvm_vm_stat {
 	struct kvm_vm_stat_generic generic;
 	u64 pages;
 	u64 hugepages;
-	u64 ipi_read_exits;
-	u64 ipi_write_exits;
-	u64 eiointc_read_exits;
-	u64 eiointc_write_exits;
-	u64 pch_pic_read_exits;
-	u64 pch_pic_write_exits;
 };
 
 struct kvm_vcpu_stat {
@@ -65,6 +59,12 @@ struct kvm_vcpu_stat {
 	u64 cpucfg_exits;
 	u64 signal_exits;
 	u64 hypercall_exits;
+	u64 ipi_read_exits;
+	u64 ipi_write_exits;
+	u64 eiointc_read_exits;
+	u64 eiointc_write_exits;
+	u64 pch_pic_read_exits;
+	u64 pch_pic_write_exits;
 };
 
 #define KVM_MEM_HUGEPAGE_CAPABLE	(1UL << 0)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index acd975ce9608..92bae1dea8eb 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -316,7 +316,7 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 		return -EINVAL;
 	}
 
-	vcpu->kvm->stat.eiointc_read_exits++;
+	vcpu->stat.eiointc_read_exits++;
 	spin_lock_irqsave(&eiointc->lock, flags);
 	switch (len) {
 	case 1:
@@ -692,7 +692,7 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 		return -EINVAL;
 	}
 
-	vcpu->kvm->stat.eiointc_write_exits++;
+	vcpu->stat.eiointc_write_exits++;
 	spin_lock_irqsave(&eiointc->lock, flags);
 	switch (len) {
 	case 1:
diff --git a/arch/loongarch/kvm/intc/ipi.c b/arch/loongarch/kvm/intc/ipi.c
index fe734dc062ed..e658d5b37c04 100644
--- a/arch/loongarch/kvm/intc/ipi.c
+++ b/arch/loongarch/kvm/intc/ipi.c
@@ -268,36 +268,16 @@ static int kvm_ipi_read(struct kvm_vcpu *vcpu,
 			struct kvm_io_device *dev,
 			gpa_t addr, int len, void *val)
 {
-	int ret;
-	struct loongarch_ipi *ipi;
-
-	ipi = vcpu->kvm->arch.ipi;
-	if (!ipi) {
-		kvm_err("%s: ipi irqchip not valid!\n", __func__);
-		return -EINVAL;
-	}
-	ipi->kvm->stat.ipi_read_exits++;
-	ret = loongarch_ipi_readl(vcpu, addr, len, val);
-
-	return ret;
+	vcpu->stat.ipi_read_exits++;
+	return loongarch_ipi_readl(vcpu, addr, len, val);
 }
 
 static int kvm_ipi_write(struct kvm_vcpu *vcpu,
 			struct kvm_io_device *dev,
 			gpa_t addr, int len, const void *val)
 {
-	int ret;
-	struct loongarch_ipi *ipi;
-
-	ipi = vcpu->kvm->arch.ipi;
-	if (!ipi) {
-		kvm_err("%s: ipi irqchip not valid!\n", __func__);
-		return -EINVAL;
-	}
-	ipi->kvm->stat.ipi_write_exits++;
-	ret = loongarch_ipi_writel(vcpu, addr, len, val);
-
-	return ret;
+	vcpu->stat.ipi_write_exits++;
+	return loongarch_ipi_writel(vcpu, addr, len, val);
 }
 
 static const struct kvm_io_device_ops kvm_ipi_ops = {
diff --git a/arch/loongarch/kvm/intc/pch_pic.c b/arch/loongarch/kvm/intc/pch_pic.c
index 08fce845f668..6f00ffe05c54 100644
--- a/arch/loongarch/kvm/intc/pch_pic.c
+++ b/arch/loongarch/kvm/intc/pch_pic.c
@@ -196,7 +196,7 @@ static int kvm_pch_pic_read(struct kvm_vcpu *vcpu,
 	}
 
 	/* statistics of pch pic reading */
-	vcpu->kvm->stat.pch_pic_read_exits++;
+	vcpu->stat.pch_pic_read_exits++;
 	ret = loongarch_pch_pic_read(s, addr, len, val);
 
 	return ret;
@@ -303,7 +303,7 @@ static int kvm_pch_pic_write(struct kvm_vcpu *vcpu,
 	}
 
 	/* statistics of pch pic writing */
-	vcpu->kvm->stat.pch_pic_write_exits++;
+	vcpu->stat.pch_pic_write_exits++;
 	ret = loongarch_pch_pic_write(s, addr, len, val);
 
 	return ret;
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index 5af32ec62cb1..d1b8c50941ca 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -20,7 +20,13 @@ const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 	STATS_DESC_COUNTER(VCPU, idle_exits),
 	STATS_DESC_COUNTER(VCPU, cpucfg_exits),
 	STATS_DESC_COUNTER(VCPU, signal_exits),
-	STATS_DESC_COUNTER(VCPU, hypercall_exits)
+	STATS_DESC_COUNTER(VCPU, hypercall_exits),
+	STATS_DESC_COUNTER(VCPU, ipi_read_exits),
+	STATS_DESC_COUNTER(VCPU, ipi_write_exits),
+	STATS_DESC_COUNTER(VCPU, eiointc_read_exits),
+	STATS_DESC_COUNTER(VCPU, eiointc_write_exits),
+	STATS_DESC_COUNTER(VCPU, pch_pic_read_exits),
+	STATS_DESC_COUNTER(VCPU, pch_pic_write_exits)
 };
 
 const struct kvm_stats_header kvm_vcpu_stats_header = {
-- 
2.39.3


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

* [PATCH v6 4/8] LoongArch: KVM: Remove never called default case statement
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (2 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 3/8] LoongArch: KVM: Add stat information with kernel irqchip Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 5/8] LoongArch: KVM: Use generic function loongarch_eiointc_read() Bibo Mao
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

IOCSR instruction supports 1/2/4/8 bytes access, len must be 1/2/4/8
bytes from iocsr exit emulation function kvm_emu_iocsr(), remove the
default case in switch case statements.

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

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 92bae1dea8eb..137cd3adca80 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -328,12 +328,9 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 	case 4:
 		ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
 		break;
-	case 8:
+	default:
 		ret = loongarch_eiointc_readq(vcpu, eiointc, addr, val);
 		break;
-	default:
-		WARN_ONCE(1, "%s: Abnormal address access: addr 0x%llx, size %d\n",
-						__func__, addr, len);
 	}
 	spin_unlock_irqrestore(&eiointc->lock, flags);
 
@@ -704,12 +701,9 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 	case 4:
 		ret = loongarch_eiointc_writel(vcpu, eiointc, addr, val);
 		break;
-	case 8:
+	default:
 		ret = loongarch_eiointc_writeq(vcpu, eiointc, addr, val);
 		break;
-	default:
-		WARN_ONCE(1, "%s: Abnormal address access: addr 0x%llx, size %d\n",
-						__func__, addr, len);
 	}
 	spin_unlock_irqrestore(&eiointc->lock, flags);
 
-- 
2.39.3


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

* [PATCH v6 5/8] LoongArch: KVM: Use generic function loongarch_eiointc_read()
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (3 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 4/8] LoongArch: KVM: Remove never called default case statement Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 6/8] LoongArch: KVM: Remove some unnecessary local variables Bibo Mao
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Generic read function loongarch_eiointc_read() is used for 1/2/4/8
bytes read access. It reads 8 bytes from emulated software state
and shift right from address offset.

Also the similar with kvm_complete_iocsr_read(), destination register
of IOCSRRD.{B/H/W} is sign extension from byte/half word/word.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 153 ++++--------------------------
 1 file changed, 17 insertions(+), 136 deletions(-)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 137cd3adca80..3e8dc844be76 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -130,134 +130,8 @@ static inline void eiointc_enable_irq(struct kvm_vcpu *vcpu,
 	}
 }
 
-static int loongarch_eiointc_readb(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, void *val)
-{
-	int index, ret = 0;
-	u8 data = 0;
-	gpa_t offset;
-
-	offset = addr - EIOINTC_BASE;
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = offset - EIOINTC_NODETYPE_START;
-		data = s->nodetype.reg_u8[index];
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		index = offset - EIOINTC_IPMAP_START;
-		data = s->ipmap.reg_u8[index];
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = offset - EIOINTC_ENABLE_START;
-		data = s->enable.reg_u8[index];
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		index = offset - EIOINTC_BOUNCE_START;
-		data = s->bounce.reg_u8[index];
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = offset - EIOINTC_COREISR_START;
-		data = s->coreisr.reg_u8[vcpu->vcpu_id][index];
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		index = offset - EIOINTC_COREMAP_START;
-		data = s->coremap.reg_u8[index];
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-	*(u8 *)val = data;
-
-	return ret;
-}
-
-static int loongarch_eiointc_readw(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, void *val)
-{
-	int index, ret = 0;
-	u16 data = 0;
-	gpa_t offset;
-
-	offset = addr - EIOINTC_BASE;
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START) >> 1;
-		data = s->nodetype.reg_u16[index];
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		index = (offset - EIOINTC_IPMAP_START) >> 1;
-		data = s->ipmap.reg_u16[index];
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START) >> 1;
-		data = s->enable.reg_u16[index];
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		index = (offset - EIOINTC_BOUNCE_START) >> 1;
-		data = s->bounce.reg_u16[index];
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START) >> 1;
-		data = s->coreisr.reg_u16[vcpu->vcpu_id][index];
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		index = (offset - EIOINTC_COREMAP_START) >> 1;
-		data = s->coremap.reg_u16[index];
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-	*(u16 *)val = data;
-
-	return ret;
-}
-
-static int loongarch_eiointc_readl(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, void *val)
-{
-	int index, ret = 0;
-	u32 data = 0;
-	gpa_t offset;
-
-	offset = addr - EIOINTC_BASE;
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START) >> 2;
-		data = s->nodetype.reg_u32[index];
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		index = (offset - EIOINTC_IPMAP_START) >> 2;
-		data = s->ipmap.reg_u32[index];
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START) >> 2;
-		data = s->enable.reg_u32[index];
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		index = (offset - EIOINTC_BOUNCE_START) >> 2;
-		data = s->bounce.reg_u32[index];
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START) >> 2;
-		data = s->coreisr.reg_u32[vcpu->vcpu_id][index];
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		index = (offset - EIOINTC_COREMAP_START) >> 2;
-		data = s->coremap.reg_u32[index];
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-	*(u32 *)val = data;
-
-	return ret;
-}
-
-static int loongarch_eiointc_readq(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
-				gpa_t addr, void *val)
+static int loongarch_eiointc_read(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
+				gpa_t addr, unsigned long *val)
 {
 	int index, ret = 0;
 	u64 data = 0;
@@ -293,7 +167,7 @@ static int loongarch_eiointc_readq(struct kvm_vcpu *vcpu, struct loongarch_eioin
 		ret = -EINVAL;
 		break;
 	}
-	*(u64 *)val = data;
+	*val = data;
 
 	return ret;
 }
@@ -303,7 +177,7 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 			gpa_t addr, int len, void *val)
 {
 	int ret = -EINVAL;
-	unsigned long flags;
+	unsigned long flags, data, offset;
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
@@ -317,24 +191,31 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 	}
 
 	vcpu->stat.eiointc_read_exits++;
+	offset = addr & 0x7;
+	addr -= offset;
 	spin_lock_irqsave(&eiointc->lock, flags);
+	ret = loongarch_eiointc_read(vcpu, eiointc, addr, &data);
+	spin_unlock_irqrestore(&eiointc->lock, flags);
+	if (ret)
+		return ret;
+
+	data = data >> (offset * 8);
 	switch (len) {
 	case 1:
-		ret = loongarch_eiointc_readb(vcpu, eiointc, addr, val);
+		*(long *)val = (s8)data;
 		break;
 	case 2:
-		ret = loongarch_eiointc_readw(vcpu, eiointc, addr, val);
+		*(long *)val = (s16)data;
 		break;
 	case 4:
-		ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
+		*(long *)val = (s32)data;
 		break;
 	default:
-		ret = loongarch_eiointc_readq(vcpu, eiointc, addr, val);
+		*(long *)val = (long)data;
 		break;
 	}
-	spin_unlock_irqrestore(&eiointc->lock, flags);
 
-	return ret;
+	return 0;
 }
 
 static int loongarch_eiointc_writeb(struct kvm_vcpu *vcpu,
-- 
2.39.3


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

* [PATCH v6 6/8] LoongArch: KVM: Remove some unnecessary local variables
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (4 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 5/8] LoongArch: KVM: Use generic function loongarch_eiointc_read() Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 7/8] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Local variable coreisr and old_coreisr is replaced with data and
old_data, and the latter is widely used in other places.

Also local variable offset is removed and addr is used directly.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 31 ++++++++++++++-----------------
 1 file changed, 14 insertions(+), 17 deletions(-)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 3e8dc844be76..bed5f7bdc8b4 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -474,15 +474,13 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 	int i, index, irq, bits, ret = 0;
 	u8 cpu;
 	u64 data, old_data;
-	u64 coreisr, old_coreisr;
-	gpa_t offset;
 
 	data = *(u64 *)val;
-	offset = addr - EIOINTC_BASE;
+	addr -= EIOINTC_BASE;
 
-	switch (offset) {
+	switch (addr) {
 	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START) >> 3;
+		index = (addr - EIOINTC_NODETYPE_START) >> 3;
 		s->nodetype.reg_u64[index] = data;
 		break;
 	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
@@ -490,11 +488,11 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		 * ipmap cannot be set at runtime, can be set only at the beginning
 		 * of irqchip driver, need not update upper irq level
 		 */
-		index = (offset - EIOINTC_IPMAP_START) >> 3;
+		index = (addr - EIOINTC_IPMAP_START) >> 3;
 		s->ipmap.reg_u64 = data;
 		break;
 	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START) >> 3;
+		index = (addr - EIOINTC_ENABLE_START) >> 3;
 		old_data = s->enable.reg_u64[index];
 		s->enable.reg_u64[index] = data;
 		/*
@@ -518,28 +516,27 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		break;
 	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
 		/* do not emulate hw bounced irq routing */
-		index = (offset - EIOINTC_BOUNCE_START) >> 3;
+		index = (addr - EIOINTC_BOUNCE_START) >> 3;
 		s->bounce.reg_u64[index] = data;
 		break;
 	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START) >> 3;
+		index = (addr - EIOINTC_COREISR_START) >> 3;
 		/* use attrs to get current cpu index */
 		cpu = vcpu->vcpu_id;
-		coreisr = data;
-		old_coreisr = s->coreisr.reg_u64[cpu][index];
+		old_data = s->coreisr.reg_u64[cpu][index];
 		/* write 1 to clear interrupt */
-		s->coreisr.reg_u64[cpu][index] = old_coreisr & ~coreisr;
-		coreisr &= old_coreisr;
+		s->coreisr.reg_u64[cpu][index] = old_data & ~data;
+		data &= old_data;
 		bits = sizeof(data) * 8;
-		irq = find_first_bit((void *)&coreisr, bits);
+		irq = find_first_bit((void *)&data, bits);
 		while (irq < bits) {
 			eiointc_update_irq(s, irq + index * bits, 0);
-			bitmap_clear((void *)&coreisr, irq, 1);
-			irq = find_first_bit((void *)&coreisr, bits);
+			bitmap_clear((void *)&data, irq, 1);
+			irq = find_first_bit((void *)&data, bits);
 		}
 		break;
 	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		irq = offset - EIOINTC_COREMAP_START;
+		irq = addr - EIOINTC_COREMAP_START;
 		index = irq >> 3;
 		s->coremap.reg_u64[index] = data;
 		eiointc_update_sw_coremap(s, irq, data, sizeof(data), true);
-- 
2.39.3


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

* [PATCH v6 7/8] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (5 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 6/8] LoongArch: KVM: Remove some unnecessary local variables Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-09  8:02 ` [PATCH v6 8/8] LoongArch: KVM: Add generic function loongarch_eiointc_write() Bibo Mao
  2025-07-16 10:19 ` [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

Function eiointc_enable_irq() checks mask value with char type, and
call eiointc_update_irq() eventually. Function eiointc_update_irq()
will update one single irq status directly.

Here it can check mask value with unsigned long type and call function
eiointc_update_irq(), that is simple and direct.

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

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index bed5f7bdc8b4..edcf87055b3c 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -471,7 +471,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
 				gpa_t addr, const void *val)
 {
-	int i, index, irq, bits, ret = 0;
+	int index, irq, ret = 0;
 	u8 cpu;
 	u64 data, old_data;
 
@@ -500,18 +500,20 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		 * update irq when isr is set.
 		 */
 		data = s->enable.reg_u64[index] & ~old_data & s->isr.reg_u64[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 1);
+		while (data) {
+			irq = __ffs(data);
+			eiointc_update_irq(s, irq + index * 64, 1);
+			data &= ~BIT_ULL(irq);
 		}
 		/*
 		 * 0: disable irq.
 		 * update irq when isr is set.
 		 */
 		data = ~s->enable.reg_u64[index] & old_data & s->isr.reg_u64[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 0);
+		while (data) {
+			irq = __ffs(data);
+			eiointc_update_irq(s, irq + index * 64, 0);
+			data &= ~BIT_ULL(irq);
 		}
 		break;
 	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
@@ -527,12 +529,10 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		/* write 1 to clear interrupt */
 		s->coreisr.reg_u64[cpu][index] = old_data & ~data;
 		data &= old_data;
-		bits = sizeof(data) * 8;
-		irq = find_first_bit((void *)&data, bits);
-		while (irq < bits) {
-			eiointc_update_irq(s, irq + index * bits, 0);
-			bitmap_clear((void *)&data, irq, 1);
-			irq = find_first_bit((void *)&data, bits);
+		while (data) {
+			irq = __ffs(data);
+			eiointc_update_irq(s, irq + index * 64, 0);
+			data &= ~BIT_ULL(irq);
 		}
 		break;
 	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-- 
2.39.3


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

* [PATCH v6 8/8] LoongArch: KVM: Add generic function loongarch_eiointc_write()
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (6 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 7/8] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
@ 2025-07-09  8:02 ` Bibo Mao
  2025-07-16 10:19 ` [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
  8 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-09  8:02 UTC (permalink / raw)
  To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel

With all eiointc iocsr register write operation with 1/2/4/8 bytes
size, generic function loongarch_eiointc_write() is used here. And
function loongarch_eiointc_writeb(), loongarch_eiointc_writew(),
loongarch_eiointc_writel() are removed.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 329 ++++--------------------------
 1 file changed, 35 insertions(+), 294 deletions(-)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index edcf87055b3c..cac59b10fa79 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -111,25 +111,6 @@ void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level)
 	spin_unlock_irqrestore(&s->lock, flags);
 }
 
-static inline void eiointc_enable_irq(struct kvm_vcpu *vcpu,
-		struct loongarch_eiointc *s, int index, u8 mask, int level)
-{
-	u8 val;
-	int irq;
-
-	val = mask & s->isr.reg_u8[index];
-	irq = ffs(val);
-	while (irq != 0) {
-		/*
-		 * enable bit change from 0 to 1,
-		 * need to update irq by pending bits
-		 */
-		eiointc_update_irq(s, irq - 1 + index * 8, level);
-		val &= ~BIT(irq - 1);
-		irq = ffs(val);
-	}
-}
-
 static int loongarch_eiointc_read(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
 				gpa_t addr, unsigned long *val)
 {
@@ -218,288 +199,42 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
 	return 0;
 }
 
-static int loongarch_eiointc_writeb(struct kvm_vcpu *vcpu,
-				struct loongarch_eiointc *s,
-				gpa_t addr, const void *val)
-{
-	int index, irq, bits, ret = 0;
-	u8 cpu;
-	u8 data, old_data;
-	u8 coreisr, old_coreisr;
-	gpa_t offset;
-
-	data = *(u8 *)val;
-	offset = addr - EIOINTC_BASE;
-
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START);
-		s->nodetype.reg_u8[index] = data;
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		/*
-		 * ipmap cannot be set at runtime, can be set only at the beginning
-		 * of irqchip driver, need not update upper irq level
-		 */
-		index = (offset - EIOINTC_IPMAP_START);
-		s->ipmap.reg_u8[index] = data;
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START);
-		old_data = s->enable.reg_u8[index];
-		s->enable.reg_u8[index] = data;
-		/*
-		 * 1: enable irq.
-		 * update irq when isr is set.
-		 */
-		data = s->enable.reg_u8[index] & ~old_data & s->isr.reg_u8[index];
-		eiointc_enable_irq(vcpu, s, index, data, 1);
-		/*
-		 * 0: disable irq.
-		 * update irq when isr is set.
-		 */
-		data = ~s->enable.reg_u8[index] & old_data & s->isr.reg_u8[index];
-		eiointc_enable_irq(vcpu, s, index, data, 0);
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		/* do not emulate hw bounced irq routing */
-		index = offset - EIOINTC_BOUNCE_START;
-		s->bounce.reg_u8[index] = data;
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START);
-		/* use attrs to get current cpu index */
-		cpu = vcpu->vcpu_id;
-		coreisr = data;
-		old_coreisr = s->coreisr.reg_u8[cpu][index];
-		/* write 1 to clear interrupt */
-		s->coreisr.reg_u8[cpu][index] = old_coreisr & ~coreisr;
-		coreisr &= old_coreisr;
-		bits = sizeof(data) * 8;
-		irq = find_first_bit((void *)&coreisr, bits);
-		while (irq < bits) {
-			eiointc_update_irq(s, irq + index * bits, 0);
-			bitmap_clear((void *)&coreisr, irq, 1);
-			irq = find_first_bit((void *)&coreisr, bits);
-		}
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		irq = offset - EIOINTC_COREMAP_START;
-		index = irq;
-		s->coremap.reg_u8[index] = data;
-		eiointc_update_sw_coremap(s, irq, data, sizeof(data), true);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu,
-				struct loongarch_eiointc *s,
-				gpa_t addr, const void *val)
-{
-	int i, index, irq, bits, ret = 0;
-	u8 cpu;
-	u16 data, old_data;
-	u16 coreisr, old_coreisr;
-	gpa_t offset;
-
-	data = *(u16 *)val;
-	offset = addr - EIOINTC_BASE;
-
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START) >> 1;
-		s->nodetype.reg_u16[index] = data;
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		/*
-		 * ipmap cannot be set at runtime, can be set only at the beginning
-		 * of irqchip driver, need not update upper irq level
-		 */
-		index = (offset - EIOINTC_IPMAP_START) >> 1;
-		s->ipmap.reg_u16[index] = data;
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START) >> 1;
-		old_data = s->enable.reg_u16[index];
-		s->enable.reg_u16[index] = data;
-		/*
-		 * 1: enable irq.
-		 * update irq when isr is set.
-		 */
-		data = s->enable.reg_u16[index] & ~old_data & s->isr.reg_u16[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 1);
-		}
-		/*
-		 * 0: disable irq.
-		 * update irq when isr is set.
-		 */
-		data = ~s->enable.reg_u16[index] & old_data & s->isr.reg_u16[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 0);
-		}
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		/* do not emulate hw bounced irq routing */
-		index = (offset - EIOINTC_BOUNCE_START) >> 1;
-		s->bounce.reg_u16[index] = data;
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START) >> 1;
-		/* use attrs to get current cpu index */
-		cpu = vcpu->vcpu_id;
-		coreisr = data;
-		old_coreisr = s->coreisr.reg_u16[cpu][index];
-		/* write 1 to clear interrupt */
-		s->coreisr.reg_u16[cpu][index] = old_coreisr & ~coreisr;
-		coreisr &= old_coreisr;
-		bits = sizeof(data) * 8;
-		irq = find_first_bit((void *)&coreisr, bits);
-		while (irq < bits) {
-			eiointc_update_irq(s, irq + index * bits, 0);
-			bitmap_clear((void *)&coreisr, irq, 1);
-			irq = find_first_bit((void *)&coreisr, bits);
-		}
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		irq = offset - EIOINTC_COREMAP_START;
-		index = irq >> 1;
-		s->coremap.reg_u16[index] = data;
-		eiointc_update_sw_coremap(s, irq, data, sizeof(data), true);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
-				struct loongarch_eiointc *s,
-				gpa_t addr, const void *val)
-{
-	int i, index, irq, bits, ret = 0;
-	u8 cpu;
-	u32 data, old_data;
-	u32 coreisr, old_coreisr;
-	gpa_t offset;
-
-	data = *(u32 *)val;
-	offset = addr - EIOINTC_BASE;
-
-	switch (offset) {
-	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
-		index = (offset - EIOINTC_NODETYPE_START) >> 2;
-		s->nodetype.reg_u32[index] = data;
-		break;
-	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
-		/*
-		 * ipmap cannot be set at runtime, can be set only at the beginning
-		 * of irqchip driver, need not update upper irq level
-		 */
-		index = (offset - EIOINTC_IPMAP_START) >> 2;
-		s->ipmap.reg_u32[index] = data;
-		break;
-	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
-		index = (offset - EIOINTC_ENABLE_START) >> 2;
-		old_data = s->enable.reg_u32[index];
-		s->enable.reg_u32[index] = data;
-		/*
-		 * 1: enable irq.
-		 * update irq when isr is set.
-		 */
-		data = s->enable.reg_u32[index] & ~old_data & s->isr.reg_u32[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 1);
-		}
-		/*
-		 * 0: disable irq.
-		 * update irq when isr is set.
-		 */
-		data = ~s->enable.reg_u32[index] & old_data & s->isr.reg_u32[index];
-		for (i = 0; i < sizeof(data); i++) {
-			u8 mask = (data >> (i * 8)) & 0xff;
-			eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 0);
-		}
-		break;
-	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
-		/* do not emulate hw bounced irq routing */
-		index = (offset - EIOINTC_BOUNCE_START) >> 2;
-		s->bounce.reg_u32[index] = data;
-		break;
-	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
-		index = (offset - EIOINTC_COREISR_START) >> 2;
-		/* use attrs to get current cpu index */
-		cpu = vcpu->vcpu_id;
-		coreisr = data;
-		old_coreisr = s->coreisr.reg_u32[cpu][index];
-		/* write 1 to clear interrupt */
-		s->coreisr.reg_u32[cpu][index] = old_coreisr & ~coreisr;
-		coreisr &= old_coreisr;
-		bits = sizeof(data) * 8;
-		irq = find_first_bit((void *)&coreisr, bits);
-		while (irq < bits) {
-			eiointc_update_irq(s, irq + index * bits, 0);
-			bitmap_clear((void *)&coreisr, irq, 1);
-			irq = find_first_bit((void *)&coreisr, bits);
-		}
-		break;
-	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		irq = offset - EIOINTC_COREMAP_START;
-		index = irq >> 2;
-		s->coremap.reg_u32[index] = data;
-		eiointc_update_sw_coremap(s, irq, data, sizeof(data), true);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
+static int loongarch_eiointc_write(struct kvm_vcpu *vcpu,
 				struct loongarch_eiointc *s,
-				gpa_t addr, const void *val)
+				gpa_t addr, u64 value, u64 field_mask)
 {
-	int index, irq, ret = 0;
+	int index, irq, offset, ret = 0;
 	u8 cpu;
-	u64 data, old_data;
+	u64 data, old, mask;
 
-	data = *(u64 *)val;
-	addr -= EIOINTC_BASE;
+	offset = addr & 7;
+	mask = field_mask << (offset * 8);
+	data = (value & field_mask) << (offset * 8);
+	addr -= EIOINTC_BASE + offset;
 
 	switch (addr) {
 	case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
 		index = (addr - EIOINTC_NODETYPE_START) >> 3;
-		s->nodetype.reg_u64[index] = data;
+		old = s->nodetype.reg_u64[index];
+		s->nodetype.reg_u64[index] = (old & ~mask) | data;
 		break;
 	case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
 		/*
 		 * ipmap cannot be set at runtime, can be set only at the beginning
 		 * of irqchip driver, need not update upper irq level
 		 */
-		index = (addr - EIOINTC_IPMAP_START) >> 3;
-		s->ipmap.reg_u64 = data;
+		old = s->ipmap.reg_u64;
+		s->ipmap.reg_u64 = (old & ~mask) | data;
 		break;
 	case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
 		index = (addr - EIOINTC_ENABLE_START) >> 3;
-		old_data = s->enable.reg_u64[index];
-		s->enable.reg_u64[index] = data;
+		old = s->enable.reg_u64[index];
+		s->enable.reg_u64[index] = (old & ~mask) | data;
 		/*
 		 * 1: enable irq.
 		 * update irq when isr is set.
 		 */
-		data = s->enable.reg_u64[index] & ~old_data & s->isr.reg_u64[index];
+		data = s->enable.reg_u64[index] & ~old & s->isr.reg_u64[index];
 		while (data) {
 			irq = __ffs(data);
 			eiointc_update_irq(s, irq + index * 64, 1);
@@ -509,7 +244,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		 * 0: disable irq.
 		 * update irq when isr is set.
 		 */
-		data = ~s->enable.reg_u64[index] & old_data & s->isr.reg_u64[index];
+		data = ~s->enable.reg_u64[index] & old & s->isr.reg_u64[index];
 		while (data) {
 			irq = __ffs(data);
 			eiointc_update_irq(s, irq + index * 64, 0);
@@ -519,16 +254,17 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 	case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
 		/* do not emulate hw bounced irq routing */
 		index = (addr - EIOINTC_BOUNCE_START) >> 3;
-		s->bounce.reg_u64[index] = data;
+		old = s->bounce.reg_u64[index];
+		s->bounce.reg_u64[index] = (old & ~mask) | data;
 		break;
 	case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
 		index = (addr - EIOINTC_COREISR_START) >> 3;
 		/* use attrs to get current cpu index */
 		cpu = vcpu->vcpu_id;
-		old_data = s->coreisr.reg_u64[cpu][index];
+		old = s->coreisr.reg_u64[cpu][index];
 		/* write 1 to clear interrupt */
-		s->coreisr.reg_u64[cpu][index] = old_data & ~data;
-		data &= old_data;
+		s->coreisr.reg_u64[cpu][index] = old & ~data;
+		data &= old;
 		while (data) {
 			irq = __ffs(data);
 			eiointc_update_irq(s, irq + index * 64, 0);
@@ -536,10 +272,11 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
 		}
 		break;
 	case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
-		irq = addr - EIOINTC_COREMAP_START;
-		index = irq >> 3;
-		s->coremap.reg_u64[index] = data;
-		eiointc_update_sw_coremap(s, irq, data, sizeof(data), true);
+		index = (addr - EIOINTC_COREMAP_START) >> 3;
+		old = s->coremap.reg_u64[index];
+		s->coremap.reg_u64[index] = (old & ~mask) | data;
+		data = s->coremap.reg_u64[index];
+		eiointc_update_sw_coremap(s, index * 8, data, sizeof(data), true);
 		break;
 	default:
 		ret = -EINVAL;
@@ -554,7 +291,7 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 			gpa_t addr, int len, const void *val)
 {
 	int ret = -EINVAL;
-	unsigned long flags;
+	unsigned long flags, value;
 	struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
 
 	if (!eiointc) {
@@ -571,16 +308,20 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
 	spin_lock_irqsave(&eiointc->lock, flags);
 	switch (len) {
 	case 1:
-		ret = loongarch_eiointc_writeb(vcpu, eiointc, addr, val);
+		value = *(unsigned char *)val;
+		ret = loongarch_eiointc_write(vcpu, eiointc, addr, value, 0xFF);
 		break;
 	case 2:
-		ret = loongarch_eiointc_writew(vcpu, eiointc, addr, val);
+		value = *(unsigned short *)val;
+		ret = loongarch_eiointc_write(vcpu, eiointc, addr, value, USHRT_MAX);
 		break;
 	case 4:
-		ret = loongarch_eiointc_writel(vcpu, eiointc, addr, val);
+		value = *(unsigned int *)val;
+		ret = loongarch_eiointc_write(vcpu, eiointc, addr, value, UINT_MAX);
 		break;
 	default:
-		ret = loongarch_eiointc_writeq(vcpu, eiointc, addr, val);
+		value = *(unsigned long *)val;
+		ret = loongarch_eiointc_write(vcpu, eiointc, addr, value, ULONG_MAX);
 		break;
 	}
 	spin_unlock_irqrestore(&eiointc->lock, flags);
-- 
2.39.3


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

* Re: [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation
  2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
                   ` (7 preceding siblings ...)
  2025-07-09  8:02 ` [PATCH v6 8/8] LoongArch: KVM: Add generic function loongarch_eiointc_write() Bibo Mao
@ 2025-07-16 10:19 ` Huacai Chen
  2025-07-17  7:14   ` Bibo Mao
  8 siblings, 1 reply; 11+ messages in thread
From: Huacai Chen @ 2025-07-16 10:19 UTC (permalink / raw)
  To: Bibo Mao; +Cc: Tianrui Zhao, Xianglai Li, kvm, loongarch, linux-kernel

Applied with some modifications. E.g., Patch6 removes offset, and
Patch8 adds it back, so I combine these two.

Since the code is a little different, it is better to test it again [1].

[1] https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git/log/?h=loongarch-kvm



Huacai

On Wed, Jul 9, 2025 at 4:02 PM Bibo Mao <maobibo@loongson.cn> wrote:
>
> This series add generic eiointc 8 bytes access interface, so that 1/2/4/8
> bytes access can use the generic 8 bytes access interface. It reduce
> about 500 lines redundant code and make eiointc emulation driver
> simpler than ever.
>
> ---
> v5 ... v6:
>   1. Merge previous patch 5 & 6 into one, patch 7 & 10 into into one and
>      patch 12 and patch 13 into one.
>   2. Use sign extension with destination register for IOCSRRD.{B/H/W}
>      kernel emulation.
>
> v4 ... v5
>   1. Rebase patch on latest kernel where bugfix of eiointc has been
>      merged.
>   2. Add generic eiointc 8 bytes access interface, 1/2/4/8 bytes access
>      uses generic 8 bytes access interface.
>
> v3 ... v4:
>   1. Remove patch about enhancement and only keep bugfix relative
>      patches.
>   2. Remove INTC indication in the patch title.
>   3. With access size, keep default case unchanged besides 1/2/4/8 since
>      here all patches are bugfix
>   4. Firstly check return value of copy_from_user() with error path,
>      keep the same order with old patch in patch 4.
>
> v2 ... v3:
>   1. Add prefix INTC: in title of every patch.
>   2. Fix array index overflow when emulate register EIOINTC_ENABLE
>      writing operation.
>   3. Add address alignment check with eiointc register access operation.
>
> v1 ... v2:
>   1. Add extra fix in patch 3 and patch 4, add num_cpu validation check
>   2. Name of stat information keeps unchanged, only move it from VM stat
>      to vCPU stat.
> ---
> Bibo Mao (8):
>   LoongArch: KVM: Use standard bitops API with eiointc
>   LoongArch: KVM: Remove unused parameter len
>   LoongArch: KVM: Add stat information with kernel irqchip
>   LoongArch: KVM: Remove never called default case statement
>   LoongArch: KVM: Use generic function loongarch_eiointc_read()
>   LoongArch: KVM: Remove some unnecessary local variables
>   LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
>   LoongArch: KVM: Add generic function loongarch_eiointc_write()
>
>  arch/loongarch/include/asm/kvm_host.h |  12 +-
>  arch/loongarch/kvm/intc/eiointc.c     | 558 ++++----------------------
>  arch/loongarch/kvm/intc/ipi.c         |  28 +-
>  arch/loongarch/kvm/intc/pch_pic.c     |   4 +-
>  arch/loongarch/kvm/vcpu.c             |   8 +-
>  5 files changed, 102 insertions(+), 508 deletions(-)
>
>
> base-commit: 733923397fd95405a48f165c9b1fbc8c4b0a4681
> --
> 2.39.3
>

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

* Re: [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation
  2025-07-16 10:19 ` [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
@ 2025-07-17  7:14   ` Bibo Mao
  0 siblings, 0 replies; 11+ messages in thread
From: Bibo Mao @ 2025-07-17  7:14 UTC (permalink / raw)
  To: Huacai Chen; +Cc: Tianrui Zhao, Xianglai Li, kvm, loongarch, linux-kernel



On 2025/7/16 下午6:19, Huacai Chen wrote:
> Applied with some modifications. E.g., Patch6 removes offset, and
> Patch8 adds it back, so I combine these two.
> 
> Since the code is a little different, it is better to test it again [1].
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git/log/?h=loongarch-kvm
It works well with basic VM operations.
Also looks good from code review side.

Regards
Bibo Mao
> 
> 
> 
> Huacai
> 
> On Wed, Jul 9, 2025 at 4:02 PM Bibo Mao <maobibo@loongson.cn> wrote:
>>
>> This series add generic eiointc 8 bytes access interface, so that 1/2/4/8
>> bytes access can use the generic 8 bytes access interface. It reduce
>> about 500 lines redundant code and make eiointc emulation driver
>> simpler than ever.
>>
>> ---
>> v5 ... v6:
>>    1. Merge previous patch 5 & 6 into one, patch 7 & 10 into into one and
>>       patch 12 and patch 13 into one.
>>    2. Use sign extension with destination register for IOCSRRD.{B/H/W}
>>       kernel emulation.
>>
>> v4 ... v5
>>    1. Rebase patch on latest kernel where bugfix of eiointc has been
>>       merged.
>>    2. Add generic eiointc 8 bytes access interface, 1/2/4/8 bytes access
>>       uses generic 8 bytes access interface.
>>
>> v3 ... v4:
>>    1. Remove patch about enhancement and only keep bugfix relative
>>       patches.
>>    2. Remove INTC indication in the patch title.
>>    3. With access size, keep default case unchanged besides 1/2/4/8 since
>>       here all patches are bugfix
>>    4. Firstly check return value of copy_from_user() with error path,
>>       keep the same order with old patch in patch 4.
>>
>> v2 ... v3:
>>    1. Add prefix INTC: in title of every patch.
>>    2. Fix array index overflow when emulate register EIOINTC_ENABLE
>>       writing operation.
>>    3. Add address alignment check with eiointc register access operation.
>>
>> v1 ... v2:
>>    1. Add extra fix in patch 3 and patch 4, add num_cpu validation check
>>    2. Name of stat information keeps unchanged, only move it from VM stat
>>       to vCPU stat.
>> ---
>> Bibo Mao (8):
>>    LoongArch: KVM: Use standard bitops API with eiointc
>>    LoongArch: KVM: Remove unused parameter len
>>    LoongArch: KVM: Add stat information with kernel irqchip
>>    LoongArch: KVM: Remove never called default case statement
>>    LoongArch: KVM: Use generic function loongarch_eiointc_read()
>>    LoongArch: KVM: Remove some unnecessary local variables
>>    LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
>>    LoongArch: KVM: Add generic function loongarch_eiointc_write()
>>
>>   arch/loongarch/include/asm/kvm_host.h |  12 +-
>>   arch/loongarch/kvm/intc/eiointc.c     | 558 ++++----------------------
>>   arch/loongarch/kvm/intc/ipi.c         |  28 +-
>>   arch/loongarch/kvm/intc/pch_pic.c     |   4 +-
>>   arch/loongarch/kvm/vcpu.c             |   8 +-
>>   5 files changed, 102 insertions(+), 508 deletions(-)
>>
>>
>> base-commit: 733923397fd95405a48f165c9b1fbc8c4b0a4681
>> --
>> 2.39.3
>>


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

end of thread, other threads:[~2025-07-17  7:16 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-09  8:02 [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
2025-07-09  8:02 ` [PATCH v6 1/8] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
2025-07-09  8:02 ` [PATCH v6 2/8] LoongArch: KVM: Remove unused parameter len Bibo Mao
2025-07-09  8:02 ` [PATCH v6 3/8] LoongArch: KVM: Add stat information with kernel irqchip Bibo Mao
2025-07-09  8:02 ` [PATCH v6 4/8] LoongArch: KVM: Remove never called default case statement Bibo Mao
2025-07-09  8:02 ` [PATCH v6 5/8] LoongArch: KVM: Use generic function loongarch_eiointc_read() Bibo Mao
2025-07-09  8:02 ` [PATCH v6 6/8] LoongArch: KVM: Remove some unnecessary local variables Bibo Mao
2025-07-09  8:02 ` [PATCH v6 7/8] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
2025-07-09  8:02 ` [PATCH v6 8/8] LoongArch: KVM: Add generic function loongarch_eiointc_write() Bibo Mao
2025-07-16 10:19 ` [PATCH v6 0/8] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
2025-07-17  7:14   ` Bibo Mao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).