Lines Matching +full:cpu +full:- +full:offset

1 // SPDX-License-Identifier: GPL-2.0
12 int ipnum, cpu, cpuid, irq; in eiointc_set_sw_coreisr() local
16 ipnum = s->ipmap.reg_u8[irq / 32]; in eiointc_set_sw_coreisr()
17 if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { in eiointc_set_sw_coreisr()
22 cpuid = s->coremap.reg_u8[irq]; in eiointc_set_sw_coreisr()
23 vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid); in eiointc_set_sw_coreisr()
27 cpu = vcpu->vcpu_id; in eiointc_set_sw_coreisr()
28 if (test_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu])) in eiointc_set_sw_coreisr()
29 __set_bit(irq, s->sw_coreisr[cpu][ipnum]); in eiointc_set_sw_coreisr()
31 __clear_bit(irq, s->sw_coreisr[cpu][ipnum]); in eiointc_set_sw_coreisr()
37 int ipnum, cpu, found; in eiointc_update_irq() local
41 ipnum = s->ipmap.reg_u8[irq / 32]; in eiointc_update_irq()
42 if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { in eiointc_update_irq()
47 cpu = s->sw_coremap[irq]; in eiointc_update_irq()
48 vcpu = kvm_get_vcpu_by_id(s->kvm, cpu); in eiointc_update_irq()
50 kvm_err("%s: invalid target cpu: %d\n", __func__, cpu); in eiointc_update_irq()
56 if (!test_bit(irq, (unsigned long *)s->enable.reg_u32)) in eiointc_update_irq()
58 __set_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]); in eiointc_update_irq()
59 found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS); in eiointc_update_irq()
60 __set_bit(irq, s->sw_coreisr[cpu][ipnum]); in eiointc_update_irq()
62 __clear_bit(irq, (unsigned long *)s->coreisr.reg_u32[cpu]); in eiointc_update_irq()
63 __clear_bit(irq, s->sw_coreisr[cpu][ipnum]); in eiointc_update_irq()
64 found = find_first_bit(s->sw_coreisr[cpu][ipnum], EIOINTC_IRQS); in eiointc_update_irq()
70 vcpu_irq.irq = level ? (INT_HWI0 + ipnum) : -(INT_HWI0 + ipnum); in eiointc_update_irq()
77 int i, cpu, cpuid; in eiointc_update_sw_coremap() local
84 if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) { in eiointc_update_sw_coremap()
85 cpuid = ffs(cpuid) - 1; in eiointc_update_sw_coremap()
89 vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid); in eiointc_update_sw_coremap()
93 cpu = vcpu->vcpu_id; in eiointc_update_sw_coremap()
94 if (s->sw_coremap[irq + i] == cpu) in eiointc_update_sw_coremap()
97 if (notify && test_bit(irq + i, (unsigned long *)s->isr.reg_u8)) { in eiointc_update_sw_coremap()
98 /* lower irq at old cpu and raise irq at new cpu */ in eiointc_update_sw_coremap()
100 s->sw_coremap[irq + i] = cpu; in eiointc_update_sw_coremap()
103 s->sw_coremap[irq + i] = cpu; in eiointc_update_sw_coremap()
111 unsigned long *isr = (unsigned long *)s->isr.reg_u8; in eiointc_set_irq()
113 spin_lock_irqsave(&s->lock, flags); in eiointc_set_irq()
116 spin_unlock_irqrestore(&s->lock, flags); in eiointc_set_irq()
124 gpa_t offset; in loongarch_eiointc_read() local
126 offset = addr - EIOINTC_BASE; in loongarch_eiointc_read()
127 switch (offset) { in loongarch_eiointc_read()
129 index = (offset - EIOINTC_NODETYPE_START) >> 3; in loongarch_eiointc_read()
130 data = s->nodetype.reg_u64[index]; in loongarch_eiointc_read()
133 index = (offset - EIOINTC_IPMAP_START) >> 3; in loongarch_eiointc_read()
134 data = s->ipmap.reg_u64; in loongarch_eiointc_read()
137 index = (offset - EIOINTC_ENABLE_START) >> 3; in loongarch_eiointc_read()
138 data = s->enable.reg_u64[index]; in loongarch_eiointc_read()
141 index = (offset - EIOINTC_BOUNCE_START) >> 3; in loongarch_eiointc_read()
142 data = s->bounce.reg_u64[index]; in loongarch_eiointc_read()
145 index = (offset - EIOINTC_COREISR_START) >> 3; in loongarch_eiointc_read()
146 data = s->coreisr.reg_u64[vcpu->vcpu_id][index]; in loongarch_eiointc_read()
149 index = (offset - EIOINTC_COREMAP_START) >> 3; in loongarch_eiointc_read()
150 data = s->coremap.reg_u64[index]; in loongarch_eiointc_read()
153 ret = -EINVAL; in loongarch_eiointc_read()
165 int ret = -EINVAL; in kvm_eiointc_read()
166 unsigned long flags, data, offset; in kvm_eiointc_read() local
167 struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc; in kvm_eiointc_read()
171 return -EINVAL; in kvm_eiointc_read()
174 if (addr & (len - 1)) { in kvm_eiointc_read()
176 return -EINVAL; in kvm_eiointc_read()
179 offset = addr & 0x7; in kvm_eiointc_read()
180 addr -= offset; in kvm_eiointc_read()
181 vcpu->stat.eiointc_read_exits++; in kvm_eiointc_read()
182 spin_lock_irqsave(&eiointc->lock, flags); in kvm_eiointc_read()
184 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_read()
188 data = data >> (offset * 8); in kvm_eiointc_read()
212 u8 cpu; in loongarch_eiointc_write() local
214 gpa_t offset; in loongarch_eiointc_write() local
216 offset = addr & 7; in loongarch_eiointc_write()
217 mask = field_mask << (offset * 8); in loongarch_eiointc_write()
218 data = (value & field_mask) << (offset * 8); in loongarch_eiointc_write()
220 addr -= offset; in loongarch_eiointc_write()
221 offset = addr - EIOINTC_BASE; in loongarch_eiointc_write()
223 switch (offset) { in loongarch_eiointc_write()
225 index = (offset - EIOINTC_NODETYPE_START) >> 3; in loongarch_eiointc_write()
226 old = s->nodetype.reg_u64[index]; in loongarch_eiointc_write()
227 s->nodetype.reg_u64[index] = (old & ~mask) | data; in loongarch_eiointc_write()
234 old = s->ipmap.reg_u64; in loongarch_eiointc_write()
235 s->ipmap.reg_u64 = (old & ~mask) | data; in loongarch_eiointc_write()
238 index = (offset - EIOINTC_ENABLE_START) >> 3; in loongarch_eiointc_write()
239 old = s->enable.reg_u64[index]; in loongarch_eiointc_write()
240 s->enable.reg_u64[index] = (old & ~mask) | data; in loongarch_eiointc_write()
245 data = s->enable.reg_u64[index] & ~old & s->isr.reg_u64[index]; in loongarch_eiointc_write()
255 data = ~s->enable.reg_u64[index] & old & s->isr.reg_u64[index]; in loongarch_eiointc_write()
264 index = (offset - EIOINTC_BOUNCE_START) >> 3; in loongarch_eiointc_write()
265 old = s->bounce.reg_u64[index]; in loongarch_eiointc_write()
266 s->bounce.reg_u64[index] = (old & ~mask) | data; in loongarch_eiointc_write()
269 index = (offset - EIOINTC_COREISR_START) >> 3; in loongarch_eiointc_write()
270 /* use attrs to get current cpu index */ in loongarch_eiointc_write()
271 cpu = vcpu->vcpu_id; in loongarch_eiointc_write()
272 old = s->coreisr.reg_u64[cpu][index]; in loongarch_eiointc_write()
274 s->coreisr.reg_u64[cpu][index] = old & ~data; in loongarch_eiointc_write()
283 index = (offset - EIOINTC_COREMAP_START) >> 3; in loongarch_eiointc_write()
284 old = s->coremap.reg_u64[index]; in loongarch_eiointc_write()
285 s->coremap.reg_u64[index] = (old & ~mask) | data; in loongarch_eiointc_write()
286 data = s->coremap.reg_u64[index]; in loongarch_eiointc_write()
290 ret = -EINVAL; in loongarch_eiointc_write()
301 int ret = -EINVAL; in kvm_eiointc_write()
303 struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc; in kvm_eiointc_write()
307 return -EINVAL; in kvm_eiointc_write()
310 if (addr & (len - 1)) { in kvm_eiointc_write()
312 return -EINVAL; in kvm_eiointc_write()
315 vcpu->stat.eiointc_write_exits++; in kvm_eiointc_write()
316 spin_lock_irqsave(&eiointc->lock, flags); in kvm_eiointc_write()
335 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_write()
351 struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc; in kvm_eiointc_virt_read()
355 return -EINVAL; in kvm_eiointc_virt_read()
358 addr -= EIOINTC_VIRT_BASE; in kvm_eiointc_virt_read()
359 spin_lock_irqsave(&eiointc->lock, flags); in kvm_eiointc_virt_read()
362 *data = eiointc->features; in kvm_eiointc_virt_read()
365 *data = eiointc->status; in kvm_eiointc_virt_read()
370 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_virt_read()
382 struct loongarch_eiointc *eiointc = vcpu->kvm->arch.eiointc; in kvm_eiointc_virt_write()
386 return -EINVAL; in kvm_eiointc_virt_write()
389 addr -= EIOINTC_VIRT_BASE; in kvm_eiointc_virt_write()
390 spin_lock_irqsave(&eiointc->lock, flags); in kvm_eiointc_virt_write()
393 ret = -EPERM; in kvm_eiointc_virt_write()
399 if ((eiointc->status & BIT(EIOINTC_ENABLE)) && value) { in kvm_eiointc_virt_write()
400 ret = -EPERM; in kvm_eiointc_virt_write()
403 eiointc->status = value & eiointc->features; in kvm_eiointc_virt_write()
408 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_virt_write()
423 unsigned long type = (unsigned long)attr->attr; in kvm_eiointc_ctrl_access()
426 struct loongarch_eiointc *s = dev->kvm->arch.eiointc; in kvm_eiointc_ctrl_access()
428 data = (void __user *)attr->addr; in kvm_eiointc_ctrl_access()
433 return -EFAULT; in kvm_eiointc_ctrl_access()
439 spin_lock_irqsave(&s->lock, flags); in kvm_eiointc_ctrl_access()
443 ret = -EINVAL; in kvm_eiointc_ctrl_access()
445 s->num_cpu = val; in kvm_eiointc_ctrl_access()
448 s->features = val; in kvm_eiointc_ctrl_access()
449 if (!(s->features & BIT(EIOINTC_HAS_VIRT_EXTENSION))) in kvm_eiointc_ctrl_access()
450 s->status |= BIT(EIOINTC_ENABLE); in kvm_eiointc_ctrl_access()
457 s->coremap.reg_u32[i], sizeof(u32), false); in kvm_eiointc_ctrl_access()
463 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_ctrl_access()
472 int addr, cpu, offset, ret = 0; in kvm_eiointc_regs_access() local
477 s = dev->kvm->arch.eiointc; in kvm_eiointc_regs_access()
478 addr = attr->attr; in kvm_eiointc_regs_access()
479 cpu = addr >> 16; in kvm_eiointc_regs_access()
483 offset = (addr - EIOINTC_NODETYPE_START) / 4; in kvm_eiointc_regs_access()
484 p = &s->nodetype.reg_u32[offset]; in kvm_eiointc_regs_access()
487 offset = (addr - EIOINTC_IPMAP_START) / 4; in kvm_eiointc_regs_access()
488 p = &s->ipmap.reg_u32[offset]; in kvm_eiointc_regs_access()
491 offset = (addr - EIOINTC_ENABLE_START) / 4; in kvm_eiointc_regs_access()
492 p = &s->enable.reg_u32[offset]; in kvm_eiointc_regs_access()
495 offset = (addr - EIOINTC_BOUNCE_START) / 4; in kvm_eiointc_regs_access()
496 p = &s->bounce.reg_u32[offset]; in kvm_eiointc_regs_access()
499 offset = (addr - EIOINTC_ISR_START) / 4; in kvm_eiointc_regs_access()
500 p = &s->isr.reg_u32[offset]; in kvm_eiointc_regs_access()
503 if (cpu >= s->num_cpu) in kvm_eiointc_regs_access()
504 return -EINVAL; in kvm_eiointc_regs_access()
506 offset = (addr - EIOINTC_COREISR_START) / 4; in kvm_eiointc_regs_access()
507 p = &s->coreisr.reg_u32[cpu][offset]; in kvm_eiointc_regs_access()
510 offset = (addr - EIOINTC_COREMAP_START) / 4; in kvm_eiointc_regs_access()
511 p = &s->coremap.reg_u32[offset]; in kvm_eiointc_regs_access()
515 return -EINVAL; in kvm_eiointc_regs_access()
518 spin_lock_irqsave(&s->lock, flags); in kvm_eiointc_regs_access()
523 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_regs_access()
537 s = dev->kvm->arch.eiointc; in kvm_eiointc_sw_status_access()
538 addr = attr->attr; in kvm_eiointc_sw_status_access()
546 p = &s->num_cpu; in kvm_eiointc_sw_status_access()
552 p = &s->features; in kvm_eiointc_sw_status_access()
555 p = &s->status; in kvm_eiointc_sw_status_access()
559 return -EINVAL; in kvm_eiointc_sw_status_access()
561 spin_lock_irqsave(&s->lock, flags); in kvm_eiointc_sw_status_access()
566 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_sw_status_access()
576 switch (attr->group) { in kvm_eiointc_get_attr()
582 if (copy_to_user((void __user *)attr->addr, &data, 4)) in kvm_eiointc_get_attr()
583 ret = -EFAULT; in kvm_eiointc_get_attr()
591 if (copy_to_user((void __user *)attr->addr, &data, 4)) in kvm_eiointc_get_attr()
592 ret = -EFAULT; in kvm_eiointc_get_attr()
596 return -EINVAL; in kvm_eiointc_get_attr()
605 switch (attr->group) { in kvm_eiointc_set_attr()
609 if (copy_from_user(&data, (void __user *)attr->addr, 4)) in kvm_eiointc_set_attr()
610 return -EFAULT; in kvm_eiointc_set_attr()
614 if (copy_from_user(&data, (void __user *)attr->addr, 4)) in kvm_eiointc_set_attr()
615 return -EFAULT; in kvm_eiointc_set_attr()
619 return -EINVAL; in kvm_eiointc_set_attr()
628 struct kvm *kvm = dev->kvm; in kvm_eiointc_create()
631 if (kvm->arch.eiointc) in kvm_eiointc_create()
632 return -EINVAL; in kvm_eiointc_create()
636 return -ENOMEM; in kvm_eiointc_create()
638 spin_lock_init(&s->lock); in kvm_eiointc_create()
639 s->kvm = kvm; in kvm_eiointc_create()
644 device = &s->device; in kvm_eiointc_create()
646 mutex_lock(&kvm->slots_lock); in kvm_eiointc_create()
649 mutex_unlock(&kvm->slots_lock); in kvm_eiointc_create()
655 device = &s->device_vext; in kvm_eiointc_create()
660 kvm_io_bus_unregister_dev(kvm, KVM_IOCSR_BUS, &s->device); in kvm_eiointc_create()
664 kvm->arch.eiointc = s; in kvm_eiointc_create()
674 if (!dev || !dev->kvm || !dev->kvm->arch.eiointc) in kvm_eiointc_destroy()
677 kvm = dev->kvm; in kvm_eiointc_destroy()
678 eiointc = kvm->arch.eiointc; in kvm_eiointc_destroy()
679 kvm_io_bus_unregister_dev(kvm, KVM_IOCSR_BUS, &eiointc->device); in kvm_eiointc_destroy()
680 kvm_io_bus_unregister_dev(kvm, KVM_IOCSR_BUS, &eiointc->device_vext); in kvm_eiointc_destroy()
685 .name = "kvm-loongarch-eiointc",