lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <CAAhV-H5Si0j0YHw11vn74hoX4bvwpZ_1xxNerhOa9Do1mgeR4w@mail.gmail.com>
Date: Sat, 22 Nov 2025 11:38:01 +0800
From: Huacai Chen <chenhuacai@...nel.org>
To: Bibo Mao <maobibo@...ngson.cn>
Cc: Tianrui Zhao <zhaotianrui@...ngson.cn>, Xianglai Li <lixianglai@...ngson.cn>, kvm@...r.kernel.org, 
	loongarch@...ts.linux.dev, linux-kernel@...r.kernel.org
Subject: Re: [PATCH] LoongArch: KVM: Use 64-bit register definition with eiointc

Applied with further simplification, if it is not correct please let me know.
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson.git/commit/?h=loongarch-next&id=a49c93149100a51e9d343a592399853601a57325

Huacai

On Tue, Oct 14, 2025 at 6:04 PM Bibo Mao <maobibo@...ngson.cn> wrote:
>
> With in-kernel emulated eiointc driver, hardware register can be
> accessed by different size, there is reg_u8/reg_u16/reg_u32/reg_u64
> union type with eiointc register.
>
> Here use 64-bit type with register definition and remove union type
> since most registers are accessed with 64-bit method. And it makes
> eiointc emulated driver simpler.
>
> Signed-off-by: Bibo Mao <maobibo@...ngson.cn>
> ---
>  arch/loongarch/include/asm/kvm_eiointc.h | 55 +++------------
>  arch/loongarch/kvm/intc/eiointc.c        | 89 +++++++++++++-----------
>  2 files changed, 57 insertions(+), 87 deletions(-)
>
> diff --git a/arch/loongarch/include/asm/kvm_eiointc.h b/arch/loongarch/include/asm/kvm_eiointc.h
> index a3a40aba8acf..8b7a2fa3f7f8 100644
> --- a/arch/loongarch/include/asm/kvm_eiointc.h
> +++ b/arch/loongarch/include/asm/kvm_eiointc.h
> @@ -10,10 +10,7 @@
>
>  #define EIOINTC_IRQS                   256
>  #define EIOINTC_ROUTE_MAX_VCPUS                256
> -#define EIOINTC_IRQS_U8_NUMS           (EIOINTC_IRQS / 8)
> -#define EIOINTC_IRQS_U16_NUMS          (EIOINTC_IRQS_U8_NUMS / 2)
> -#define EIOINTC_IRQS_U32_NUMS          (EIOINTC_IRQS_U8_NUMS / 4)
> -#define EIOINTC_IRQS_U64_NUMS          (EIOINTC_IRQS_U8_NUMS / 8)
> +#define EIOINTC_IRQS_U64_NUMS          (EIOINTC_IRQS / 64)
>  /* map to ipnum per 32 irqs */
>  #define EIOINTC_IRQS_NODETYPE_COUNT    16
>
> @@ -64,54 +61,18 @@ struct loongarch_eiointc {
>         uint32_t status;
>
>         /* hardware state */
> -       union nodetype {
> -               u64 reg_u64[EIOINTC_IRQS_NODETYPE_COUNT / 4];
> -               u32 reg_u32[EIOINTC_IRQS_NODETYPE_COUNT / 2];
> -               u16 reg_u16[EIOINTC_IRQS_NODETYPE_COUNT];
> -               u8 reg_u8[EIOINTC_IRQS_NODETYPE_COUNT * 2];
> -       } nodetype;
> +       u64 nodetype[EIOINTC_IRQS_NODETYPE_COUNT / 4];
>
>         /* one bit shows the state of one irq */
> -       union bounce {
> -               u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
> -               u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
> -               u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
> -               u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
> -       } bounce;
> -
> -       union isr {
> -               u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
> -               u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
> -               u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
> -               u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
> -       } isr;
> -       union coreisr {
> -               u64 reg_u64[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS];
> -               u32 reg_u32[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U32_NUMS];
> -               u16 reg_u16[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U16_NUMS];
> -               u8 reg_u8[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U8_NUMS];
> -       } coreisr;
> -       union enable {
> -               u64 reg_u64[EIOINTC_IRQS_U64_NUMS];
> -               u32 reg_u32[EIOINTC_IRQS_U32_NUMS];
> -               u16 reg_u16[EIOINTC_IRQS_U16_NUMS];
> -               u8 reg_u8[EIOINTC_IRQS_U8_NUMS];
> -       } enable;
> +       u64 bounce[EIOINTC_IRQS_U64_NUMS];
> +       u64 isr[EIOINTC_IRQS_U64_NUMS];
> +       u64 coreisr[EIOINTC_ROUTE_MAX_VCPUS][EIOINTC_IRQS_U64_NUMS];
> +       u64 enable[EIOINTC_IRQS_U64_NUMS];
>
>         /* use one byte to config ipmap for 32 irqs at once */
> -       union ipmap {
> -               u64 reg_u64;
> -               u32 reg_u32[EIOINTC_IRQS_U32_NUMS / 4];
> -               u16 reg_u16[EIOINTC_IRQS_U16_NUMS / 4];
> -               u8 reg_u8[EIOINTC_IRQS_U8_NUMS / 4];
> -       } ipmap;
> +       u64 ipmap;
>         /* use one byte to config coremap for one irq */
> -       union coremap {
> -               u64 reg_u64[EIOINTC_IRQS / 8];
> -               u32 reg_u32[EIOINTC_IRQS / 4];
> -               u16 reg_u16[EIOINTC_IRQS / 2];
> -               u8 reg_u8[EIOINTC_IRQS];
> -       } coremap;
> +       u64 coremap[EIOINTC_IRQS / 8];
>
>         DECLARE_BITMAP(sw_coreisr[EIOINTC_ROUTE_MAX_VCPUS][LOONGSON_IP_NUM], EIOINTC_IRQS);
>         uint8_t  sw_coremap[EIOINTC_IRQS];
> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
> index c32333695381..eecdc8f4a565 100644
> --- a/arch/loongarch/kvm/intc/eiointc.c
> +++ b/arch/loongarch/kvm/intc/eiointc.c
> @@ -11,21 +11,23 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
>  {
>         int ipnum, cpu, cpuid, irq;
>         struct kvm_vcpu *vcpu;
> +       u8 *coremap;
>
> +       coremap = (u8 *)s->coremap;
>         for (irq = 0; irq < EIOINTC_IRQS; irq++) {
> -               ipnum = s->ipmap.reg_u8[irq / 32];
> +               ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xFF;
>                 if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>                         ipnum = count_trailing_zeros(ipnum);
>                         ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0;
>                 }
>
> -               cpuid = s->coremap.reg_u8[irq];
> +               cpuid = coremap[irq];
>                 vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
>                 if (!vcpu)
>                         continue;
>
>                 cpu = vcpu->vcpu_id;
> -               if (test_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]))
> +               if (test_bit(irq, (unsigned long *)s->coreisr[cpu]))
>                         __set_bit(irq, s->sw_coreisr[cpu][ipnum]);
>                 else
>                         __clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
> @@ -38,7 +40,7 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>         struct kvm_vcpu *vcpu;
>         struct kvm_interrupt vcpu_irq;
>
> -       ipnum = s->ipmap.reg_u8[irq / 32];
> +       ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xFF;
>         if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>                 ipnum = count_trailing_zeros(ipnum);
>                 ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0;
> @@ -53,13 +55,13 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>
>         if (level) {
>                 /* if not enable return false */
> -               if (!test_bit(irq, (unsigned long *)s->enable.reg_u32))
> +               if (!test_bit(irq, (unsigned long *)s->enable))
>                         return;
> -               __set_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]);
> +               __set_bit(irq, (unsigned long *)s->coreisr[cpu]);
>                 found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
>                 __set_bit(irq, s->sw_coreisr[cpu][ipnum]);
>         } else {
> -               __clear_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]);
> +               __clear_bit(irq, (unsigned long *)s->coreisr[cpu]);
>                 __clear_bit(irq, s->sw_coreisr[cpu][ipnum]);
>                 found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS);
>         }
> @@ -94,7 +96,7 @@ static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,
>                 if (s->sw_coremap[irq + i] == cpu)
>                         continue;
>
> -               if (notify && test_bit(irq + i, (unsigned long *)s->isr.reg_u8)) {
> +               if (notify && test_bit(irq + i, (unsigned long *)s->isr)) {
>                         /* lower irq at old cpu and raise irq at new cpu */
>                         eiointc_update_irq(s, irq + i, 0);
>                         s->sw_coremap[irq + i] = cpu;
> @@ -108,7 +110,7 @@ static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s,
>  void eiointc_set_irq(struct loongarch_eiointc *s, int irq, int level)
>  {
>         unsigned long flags;
> -       unsigned long *isr = (unsigned long *)s->isr.reg_u8;
> +       unsigned long *isr = (unsigned long *)s->isr;
>
>         spin_lock_irqsave(&s->lock, flags);
>         level ? __set_bit(irq, isr) : __clear_bit(irq, isr);
> @@ -127,27 +129,27 @@ static int loongarch_eiointc_read(struct kvm_vcpu *vcpu, struct loongarch_eioint
>         switch (offset) {
>         case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
>                 index = (offset - EIOINTC_NODETYPE_START) >> 3;
> -               data = s->nodetype.reg_u64[index];
> +               data = s->nodetype[index];
>                 break;
>         case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
>                 index = (offset - EIOINTC_IPMAP_START) >> 3;
> -               data = s->ipmap.reg_u64;
> +               data = s->ipmap;
>                 break;
>         case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
>                 index = (offset - EIOINTC_ENABLE_START) >> 3;
> -               data = s->enable.reg_u64[index];
> +               data = s->enable[index];
>                 break;
>         case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
>                 index = (offset - EIOINTC_BOUNCE_START) >> 3;
> -               data = s->bounce.reg_u64[index];
> +               data = s->bounce[index];
>                 break;
>         case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
>                 index = (offset - EIOINTC_COREISR_START) >> 3;
> -               data = s->coreisr.reg_u64[vcpu->vcpu_id][index];
> +               data = s->coreisr[vcpu->vcpu_id][index];
>                 break;
>         case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
>                 index = (offset - EIOINTC_COREMAP_START) >> 3;
> -               data = s->coremap.reg_u64[index];
> +               data = s->coremap[index];
>                 break;
>         default:
>                 ret = -EINVAL;
> @@ -223,26 +225,26 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu,
>         switch (offset) {
>         case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
>                 index = (offset - EIOINTC_NODETYPE_START) >> 3;
> -               old = s->nodetype.reg_u64[index];
> -               s->nodetype.reg_u64[index] = (old & ~mask) | data;
> +               old = s->nodetype[index];
> +               s->nodetype[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
>                  */
> -               old = s->ipmap.reg_u64;
> -               s->ipmap.reg_u64 = (old & ~mask) | data;
> +               old = s->ipmap;
> +               s->ipmap = (old & ~mask) | data;
>                 break;
>         case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
>                 index = (offset - EIOINTC_ENABLE_START) >> 3;
> -               old = s->enable.reg_u64[index];
> -               s->enable.reg_u64[index] = (old & ~mask) | data;
> +               old = s->enable[index];
> +               s->enable[index] = (old & ~mask) | data;
>                 /*
>                  * 1: enable irq.
>                  * update irq when isr is set.
>                  */
> -               data = s->enable.reg_u64[index] & ~old & s->isr.reg_u64[index];
> +               data = s->enable[index] & ~old & s->isr[index];
>                 while (data) {
>                         irq = __ffs(data);
>                         eiointc_update_irq(s, irq + index * 64, 1);
> @@ -252,7 +254,7 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu,
>                  * 0: disable irq.
>                  * update irq when isr is set.
>                  */
> -               data = ~s->enable.reg_u64[index] & old & s->isr.reg_u64[index];
> +               data = ~s->enable[index] & old & s->isr[index];
>                 while (data) {
>                         irq = __ffs(data);
>                         eiointc_update_irq(s, irq + index * 64, 0);
> @@ -262,16 +264,16 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu,
>         case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
>                 /* do not emulate hw bounced irq routing */
>                 index = (offset - EIOINTC_BOUNCE_START) >> 3;
> -               old = s->bounce.reg_u64[index];
> -               s->bounce.reg_u64[index] = (old & ~mask) | data;
> +               old = s->bounce[index];
> +               s->bounce[index] = (old & ~mask) | data;
>                 break;
>         case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
>                 index = (offset - EIOINTC_COREISR_START) >> 3;
>                 /* use attrs to get current cpu index */
>                 cpu = vcpu->vcpu_id;
> -               old = s->coreisr.reg_u64[cpu][index];
> +               old = s->coreisr[cpu][index];
>                 /* write 1 to clear interrupt */
> -               s->coreisr.reg_u64[cpu][index] = old & ~data;
> +               s->coreisr[cpu][index] = old & ~data;
>                 data &= old;
>                 while (data) {
>                         irq = __ffs(data);
> @@ -281,9 +283,9 @@ static int loongarch_eiointc_write(struct kvm_vcpu *vcpu,
>                 break;
>         case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
>                 index = (offset - EIOINTC_COREMAP_START) >> 3;
> -               old = s->coremap.reg_u64[index];
> -               s->coremap.reg_u64[index] = (old & ~mask) | data;
> -               data = s->coremap.reg_u64[index];
> +               old = s->coremap[index];
> +               s->coremap[index] = (old & ~mask) | data;
> +               data = s->coremap[index];
>                 eiointc_update_sw_coremap(s, index * 8, data, sizeof(data), true);
>                 break;
>         default:
> @@ -451,10 +453,10 @@ static int kvm_eiointc_ctrl_access(struct kvm_device *dev,
>                 break;
>         case KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED:
>                 eiointc_set_sw_coreisr(s);
> -               for (i = 0; i < (EIOINTC_IRQS / 4); i++) {
> -                       start_irq = i * 4;
> +               for (i = 0; i < (EIOINTC_IRQS / 8); i++) {
> +                       start_irq = i * 8;
>                         eiointc_update_sw_coremap(s, start_irq,
> -                                       s->coremap.reg_u32[i], sizeof(u32), false);
> +                                       s->coremap[i], sizeof(u64), false);
>                 }
>                 break;
>         default:
> @@ -481,34 +483,41 @@ static int kvm_eiointc_regs_access(struct kvm_device *dev,
>         switch (addr) {
>         case EIOINTC_NODETYPE_START ... EIOINTC_NODETYPE_END:
>                 offset = (addr - EIOINTC_NODETYPE_START) / 4;
> -               p = &s->nodetype.reg_u32[offset];
> +               p = s->nodetype;
> +               p += offset * 4;
>                 break;
>         case EIOINTC_IPMAP_START ... EIOINTC_IPMAP_END:
>                 offset = (addr - EIOINTC_IPMAP_START) / 4;
> -               p = &s->ipmap.reg_u32[offset];
> +               p = &s->ipmap;
> +               p += offset * 4;
>                 break;
>         case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
>                 offset = (addr - EIOINTC_ENABLE_START) / 4;
> -               p = &s->enable.reg_u32[offset];
> +               p = s->enable;
> +               p += offset * 4;
>                 break;
>         case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
>                 offset = (addr - EIOINTC_BOUNCE_START) / 4;
> -               p = &s->bounce.reg_u32[offset];
> +               p = s->bounce;
> +               p += offset * 4;
>                 break;
>         case EIOINTC_ISR_START ... EIOINTC_ISR_END:
>                 offset = (addr - EIOINTC_ISR_START) / 4;
> -               p = &s->isr.reg_u32[offset];
> +               p = s->isr;
> +               p += offset * 4;
>                 break;
>         case EIOINTC_COREISR_START ... EIOINTC_COREISR_END:
>                 if (cpu >= s->num_cpu)
>                         return -EINVAL;
>
>                 offset = (addr - EIOINTC_COREISR_START) / 4;
> -               p = &s->coreisr.reg_u32[cpu][offset];
> +               p = s->coreisr[cpu];
> +               p += offset * 4;
>                 break;
>         case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END:
>                 offset = (addr - EIOINTC_COREMAP_START) / 4;
> -               p = &s->coremap.reg_u32[offset];
> +               p = s->coremap;
> +               p += offset * 4;
>                 break;
>         default:
>                 kvm_err("%s: unknown eiointc register, addr = %d\n", __func__, addr);
>
> base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
> --
> 2.39.3
>
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ