* [PATCH v5 01/13] LoongArch: KVM: Use standard bitops API with eiointc
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 02/13] LoongArch: KVM: Remove unused parameter len Bibo Mao
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 [flat|nested] 16+ messages in thread* [PATCH v5 02/13] LoongArch: KVM: Remove unused parameter len
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
2025-07-01 3:08 ` [PATCH v5 01/13] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 03/13] LoongArch: KVM: Add stat information with kernel irqchip Bibo Mao
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 [flat|nested] 16+ messages in thread* [PATCH v5 03/13] LoongArch: KVM: Add stat information with kernel irqchip
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
2025-07-01 3:08 ` [PATCH v5 01/13] LoongArch: KVM: Use standard bitops API with eiointc Bibo Mao
2025-07-01 3:08 ` [PATCH v5 02/13] LoongArch: KVM: Remove unused parameter len Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 04/13] LoongArch: KVM: Remove never called default case statement Bibo Mao
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 [flat|nested] 16+ messages in thread* [PATCH v5 04/13] LoongArch: KVM: Remove never called default case statement
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (2 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 03/13] LoongArch: KVM: Add stat information with kernel irqchip Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 05/13] LoongArch: KVM: Rename loongarch_eiointc_readq with loongarch_eiointc_read Bibo Mao
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 [flat|nested] 16+ messages in thread* [PATCH v5 05/13] LoongArch: KVM: Rename loongarch_eiointc_readq with loongarch_eiointc_read
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (3 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 04/13] LoongArch: KVM: Remove never called default case statement Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 06/13] LoongArch: KVM: Use generic read function loongarch_eiointc_read Bibo Mao
` (4 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 UTC (permalink / raw)
To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel
General function loongarch_eiointc_read() will be used for 1/2/4/8
bytes read access, it comes from loongarch_eiointc_readq().
Here rename function loongarch_eiointc_readq() with
loongarch_eiointc_read().
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 137cd3adca80..e169b96b7e5c 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -256,8 +256,8 @@ static int loongarch_eiointc_readl(struct kvm_vcpu *vcpu, struct loongarch_eioin
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 +293,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 +303,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;
struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
if (!eiointc) {
@@ -329,7 +329,8 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu,
ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
break;
default:
- ret = loongarch_eiointc_readq(vcpu, eiointc, addr, val);
+ ret = loongarch_eiointc_read(vcpu, eiointc, addr, &data);
+ *(u64 *)val = data;
break;
}
spin_unlock_irqrestore(&eiointc->lock, flags);
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v5 06/13] LoongArch: KVM: Use generic read function loongarch_eiointc_read
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (4 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 05/13] LoongArch: KVM: Rename loongarch_eiointc_readq with loongarch_eiointc_read Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 07/13] LoongArch: KVM: Remove some unnecessary local variables Bibo Mao
` (3 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 left from address offset.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 146 +++---------------------------
1 file changed, 13 insertions(+), 133 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index e169b96b7e5c..b49611c00b0e 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -130,132 +130,6 @@ 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_read(struct kvm_vcpu *vcpu, struct loongarch_eiointc *s,
gpa_t addr, unsigned long *val)
{
@@ -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, data;
+ unsigned long flags, data, offset;
struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc;
if (!eiointc) {
@@ -317,25 +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);
+ *(u8 *)val = (u8)data;
break;
case 2:
- ret = loongarch_eiointc_readw(vcpu, eiointc, addr, val);
+ *(u16 *)val = (u16)data;
break;
case 4:
- ret = loongarch_eiointc_readl(vcpu, eiointc, addr, val);
+ *(u32 *)val = (u32)data;
break;
default:
- ret = loongarch_eiointc_read(vcpu, eiointc, addr, &data);
*(u64 *)val = 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 [flat|nested] 16+ messages in thread* [PATCH v5 07/13] LoongArch: KVM: Remove some unnecessary local variables
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (5 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 06/13] LoongArch: KVM: Use generic read function loongarch_eiointc_read Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:08 ` [PATCH v5 08/13] LoongArch: KVM: Use concise api __ffs() Bibo Mao
` (2 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 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 sentences.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index b49611c00b0e..31f2c7476d6f 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -474,7 +474,6 @@ 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;
@@ -525,17 +524,16 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
index = (offset - 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:
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v5 08/13] LoongArch: KVM: Use concise api __ffs()
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (6 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 07/13] LoongArch: KVM: Remove some unnecessary local variables Bibo Mao
@ 2025-07-01 3:08 ` Bibo Mao
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
2025-07-01 10:48 ` [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
9 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:08 UTC (permalink / raw)
To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel
Function __ffs() is simpler than API find_first_bit() since parameter
data is unsigned long type.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 31f2c7476d6f..5b5b3a73a4fb 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 i, index, irq, ret = 0;
u8 cpu;
u64 data, old_data;
gpa_t offset;
@@ -528,12 +528,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 [flat|nested] 16+ messages in thread* [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (7 preceding siblings ...)
2025-07-01 3:08 ` [PATCH v5 08/13] LoongArch: KVM: Use concise api __ffs() Bibo Mao
@ 2025-07-01 3:15 ` Bibo Mao
2025-07-01 3:15 ` [PATCH v5 10/13] LoongArch: KVM: Remove local variable offset Bibo Mao
` (3 more replies)
2025-07-01 10:48 ` [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
9 siblings, 4 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:15 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 | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 5b5b3a73a4fb..5f2c291049b1 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, ret = 0;
+ int index, irq, ret = 0;
u8 cpu;
u64 data, old_data;
gpa_t offset;
@@ -501,18 +501,21 @@ 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:
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v5 10/13] LoongArch: KVM: Remove local variable offset
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
@ 2025-07-01 3:15 ` Bibo Mao
2025-07-01 3:15 ` [PATCH v5 11/13] LoongArch: KVM: Rename old_data with old Bibo Mao
` (2 subsequent siblings)
3 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:15 UTC (permalink / raw)
To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel
Local variable offset is removed and addr is used directly.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 5f2c291049b1..c2687fbee106 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -474,14 +474,13 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
int index, irq, ret = 0;
u8 cpu;
u64 data, old_data;
- 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:
@@ -489,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;
/*
@@ -520,11 +519,11 @@ 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;
old_data = s->coreisr.reg_u64[cpu][index];
@@ -538,7 +537,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
}
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 [flat|nested] 16+ messages in thread* [PATCH v5 11/13] LoongArch: KVM: Rename old_data with old
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
2025-07-01 3:15 ` [PATCH v5 10/13] LoongArch: KVM: Remove local variable offset Bibo Mao
@ 2025-07-01 3:15 ` Bibo Mao
2025-07-01 3:15 ` [PATCH v5 12/13] LoongArch: KVM: Add generic function loongarch_eiointc_write() Bibo Mao
2025-07-01 3:15 ` [PATCH v5 13/13] LoongArch: KVM: Use generic interface loongarch_eiointc_write() Bibo Mao
3 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:15 UTC (permalink / raw)
To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel
For simplicity, rename local variable old_data with old.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index c2687fbee106..7844463ee2b9 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -473,7 +473,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
{
int index, irq, ret = 0;
u8 cpu;
- u64 data, old_data;
+ u64 data, old;
data = *(u64 *)val;
addr -= EIOINTC_BASE;
@@ -488,18 +488,17 @@ 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 = (addr - EIOINTC_IPMAP_START) >> 3;
s->ipmap.reg_u64 = data;
break;
case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
index = (addr - EIOINTC_ENABLE_START) >> 3;
- old_data = s->enable.reg_u64[index];
+ old = s->enable.reg_u64[index];
s->enable.reg_u64[index] = 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);
@@ -510,7 +509,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);
@@ -526,10 +525,10 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
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);
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH v5 12/13] LoongArch: KVM: Add generic function loongarch_eiointc_write()
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
2025-07-01 3:15 ` [PATCH v5 10/13] LoongArch: KVM: Remove local variable offset Bibo Mao
2025-07-01 3:15 ` [PATCH v5 11/13] LoongArch: KVM: Rename old_data with old Bibo Mao
@ 2025-07-01 3:15 ` Bibo Mao
2025-07-01 3:15 ` [PATCH v5 13/13] LoongArch: KVM: Use generic interface loongarch_eiointc_write() Bibo Mao
3 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:15 UTC (permalink / raw)
To: Tianrui Zhao, Huacai Chen, Xianglai Li; +Cc: kvm, loongarch, linux-kernel
Function loongarch_eiointc_write() is added for 1/2/4/8 bytes eiointc
register write operation. Parameter field_mask is alternative meaning
of length.
Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
arch/loongarch/kvm/intc/eiointc.c | 39 ++++++++++++++++++-------------
1 file changed, 23 insertions(+), 16 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 7844463ee2b9..105764c1a735 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -467,33 +467,37 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
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;
+ 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
*/
- 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 = s->enable.reg_u64[index];
- s->enable.reg_u64[index] = data;
+ s->enable.reg_u64[index] = (old & ~mask) | data;
/*
* 1: enable irq.
* update irq when isr is set.
@@ -519,7 +523,8 @@ 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;
@@ -536,10 +541,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 +560,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) {
@@ -580,7 +586,8 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu,
ret = loongarch_eiointc_writel(vcpu, eiointc, addr, val);
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 [flat|nested] 16+ messages in thread* [PATCH v5 13/13] LoongArch: KVM: Use generic interface loongarch_eiointc_write()
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
` (2 preceding siblings ...)
2025-07-01 3:15 ` [PATCH v5 12/13] LoongArch: KVM: Add generic function loongarch_eiointc_write() Bibo Mao
@ 2025-07-01 3:15 ` Bibo Mao
3 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-01 3:15 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 | 277 +-----------------------------
1 file changed, 6 insertions(+), 271 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 105764c1a735..3a059f10575b 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,255 +199,6 @@ 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_write(struct kvm_vcpu *vcpu,
struct loongarch_eiointc *s,
gpa_t addr, u64 value, u64 field_mask)
@@ -577,13 +309,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, 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:
value = *(unsigned long *)val;
--
2.39.3
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation
2025-07-01 3:08 [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Bibo Mao
` (8 preceding siblings ...)
2025-07-01 3:15 ` [PATCH v5 09/13] LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq() Bibo Mao
@ 2025-07-01 10:48 ` Huacai Chen
2025-07-07 3:51 ` Bibo Mao
9 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2025-07-01 10:48 UTC (permalink / raw)
To: Bibo Mao; +Cc: Tianrui Zhao, Xianglai Li, kvm, loongarch, linux-kernel
Hi, Bibo,
On Tue, Jul 1, 2025 at 11:08 AM 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 300 lines redundant code and make eiointc emulation driver simple
> than ever.
>
> ---
> 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 (13):
> 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: Rename loongarch_eiointc_readq with
> loongarch_eiointc_read
> LoongArch: KVM: Use generic read function loongarch_eiointc_read
> LoongArch: KVM: Remove some unnecessary local variables
> LoongArch: KVM: Use concise api __ffs()
> LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
> LoongArch: KVM: Remove local variable offset
> LoongArch: KVM: Rename old_data with old
> LoongArch: KVM: Add generic function loongarch_eiointc_write()
> LoongArch: KVM: Use generic interface loongarch_eiointc_write()
Patch5 and Patch6 can be squashed, Patch7 and Patch10 can be squashed,
Patch8 and Patch9 can be squshed, Patch12 and Patch13 can be squashed,
Patch11 is useless so can be removed.
Huacai
>
> arch/loongarch/include/asm/kvm_host.h | 12 +-
> arch/loongarch/kvm/intc/eiointc.c | 557 ++++----------------------
> 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(+), 507 deletions(-)
>
>
> base-commit: d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af
> --
> 2.39.3
>
^ permalink raw reply [flat|nested] 16+ messages in thread* Re: [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation
2025-07-01 10:48 ` [PATCH v5 00/13] LoongArch: KVM: Enhancement with eiointc emulation Huacai Chen
@ 2025-07-07 3:51 ` Bibo Mao
0 siblings, 0 replies; 16+ messages in thread
From: Bibo Mao @ 2025-07-07 3:51 UTC (permalink / raw)
To: Huacai Chen; +Cc: Tianrui Zhao, Xianglai Li, kvm, loongarch, linux-kernel
On 2025/7/1 下午6:48, Huacai Chen wrote:
> Hi, Bibo,
>
> On Tue, Jul 1, 2025 at 11:08 AM 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 300 lines redundant code and make eiointc emulation driver simple
>> than ever.
>>
>> ---
>> 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 (13):
>> 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: Rename loongarch_eiointc_readq with
>> loongarch_eiointc_read
>> LoongArch: KVM: Use generic read function loongarch_eiointc_read
>> LoongArch: KVM: Remove some unnecessary local variables
>> LoongArch: KVM: Use concise api __ffs()
>> LoongArch: KVM: Replace eiointc_enable_irq() with eiointc_update_irq()
>> LoongArch: KVM: Remove local variable offset
>> LoongArch: KVM: Rename old_data with old
>> LoongArch: KVM: Add generic function loongarch_eiointc_write()
>> LoongArch: KVM: Use generic interface loongarch_eiointc_write()
> Patch5 and Patch6 can be squashed, Patch7 and Patch10 can be squashed,
> Patch8 and Patch9 can be squshed, Patch12 and Patch13 can be squashed,
> Patch11 is useless so can be removed.
Thanks for reviewing, will do in this way.
Regards
Bibo Mao
>
>
> Huacai
>
>>
>> arch/loongarch/include/asm/kvm_host.h | 12 +-
>> arch/loongarch/kvm/intc/eiointc.c | 557 ++++----------------------
>> 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(+), 507 deletions(-)
>>
>>
>> base-commit: d0b3b7b22dfa1f4b515fd3a295b3fd958f9e81af
>> --
>> 2.39.3
>>
^ permalink raw reply [flat|nested] 16+ messages in thread