Lines Matching +full:4 +full:- +full:data
1 // SPDX-License-Identifier: GPL-2.0
16 ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff; in eiointc_set_sw_coreisr()
17 if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { in eiointc_set_sw_coreisr()
19 ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0; in eiointc_set_sw_coreisr()
22 cpuid = ((u8 *)s->coremap)[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[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()
41 ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff; in eiointc_update_irq()
42 if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) { in eiointc_update_irq()
44 ipnum = (ipnum >= 0 && ipnum < 4) ? ipnum : 0; 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()
56 if (!test_bit(irq, (unsigned long *)s->enable)) in eiointc_update_irq()
58 __set_bit(irq, (unsigned long *)s->coreisr[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[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()
84 if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) { in eiointc_update_sw_coremap()
85 cpuid = ffs(cpuid) - 1; in eiointc_update_sw_coremap()
86 cpuid = (cpuid >= 4) ? 0 : cpuid; 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)) { 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; 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()
123 u64 data = 0; in loongarch_eiointc_read() local
126 offset = addr - EIOINTC_BASE; in loongarch_eiointc_read()
129 index = (offset - EIOINTC_NODETYPE_START) >> 3; in loongarch_eiointc_read()
130 data = s->nodetype[index]; in loongarch_eiointc_read()
133 index = (offset - EIOINTC_IPMAP_START) >> 3; in loongarch_eiointc_read()
134 data = s->ipmap; in loongarch_eiointc_read()
137 index = (offset - EIOINTC_ENABLE_START) >> 3; in loongarch_eiointc_read()
138 data = s->enable[index]; in loongarch_eiointc_read()
141 index = (offset - EIOINTC_BOUNCE_START) >> 3; in loongarch_eiointc_read()
142 data = s->bounce[index]; in loongarch_eiointc_read()
145 index = (offset - EIOINTC_COREISR_START) >> 3; in loongarch_eiointc_read()
146 data = s->coreisr[vcpu->vcpu_id][index]; in loongarch_eiointc_read()
149 index = (offset - EIOINTC_COREMAP_START) >> 3; in loongarch_eiointc_read()
150 data = s->coremap[index]; in loongarch_eiointc_read()
153 ret = -EINVAL; in loongarch_eiointc_read()
156 *val = data; 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()
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()
183 ret = loongarch_eiointc_read(vcpu, eiointc, addr, &data); in kvm_eiointc_read()
184 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_read()
188 data = data >> (offset * 8); in kvm_eiointc_read()
191 *(long *)val = (s8)data; in kvm_eiointc_read()
194 *(long *)val = (s16)data; in kvm_eiointc_read()
196 case 4: in kvm_eiointc_read()
197 *(long *)val = (s32)data; in kvm_eiointc_read()
200 *(long *)val = (long)data; in kvm_eiointc_read()
213 u64 data, old, mask; in loongarch_eiointc_write() local
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()
225 index = (offset - EIOINTC_NODETYPE_START) >> 3; in loongarch_eiointc_write()
226 old = s->nodetype[index]; in loongarch_eiointc_write()
227 s->nodetype[index] = (old & ~mask) | data; in loongarch_eiointc_write()
234 old = s->ipmap; in loongarch_eiointc_write()
235 s->ipmap = (old & ~mask) | data; in loongarch_eiointc_write()
238 index = (offset - EIOINTC_ENABLE_START) >> 3; in loongarch_eiointc_write()
239 old = s->enable[index]; in loongarch_eiointc_write()
240 s->enable[index] = (old & ~mask) | data; in loongarch_eiointc_write()
245 data = s->enable[index] & ~old & s->isr[index]; in loongarch_eiointc_write()
246 while (data) { in loongarch_eiointc_write()
247 irq = __ffs(data); in loongarch_eiointc_write()
249 data &= ~BIT_ULL(irq); in loongarch_eiointc_write()
255 data = ~s->enable[index] & old & s->isr[index]; in loongarch_eiointc_write()
256 while (data) { in loongarch_eiointc_write()
257 irq = __ffs(data); in loongarch_eiointc_write()
259 data &= ~BIT_ULL(irq); in loongarch_eiointc_write()
264 index = (offset - EIOINTC_BOUNCE_START) >> 3; in loongarch_eiointc_write()
265 old = s->bounce[index]; in loongarch_eiointc_write()
266 s->bounce[index] = (old & ~mask) | data; in loongarch_eiointc_write()
269 index = (offset - EIOINTC_COREISR_START) >> 3; in loongarch_eiointc_write()
271 cpu = vcpu->vcpu_id; in loongarch_eiointc_write()
272 old = s->coreisr[cpu][index]; in loongarch_eiointc_write()
274 s->coreisr[cpu][index] = old & ~data; in loongarch_eiointc_write()
275 data &= old; in loongarch_eiointc_write()
276 while (data) { in loongarch_eiointc_write()
277 irq = __ffs(data); in loongarch_eiointc_write()
279 data &= ~BIT_ULL(irq); in loongarch_eiointc_write()
283 index = (offset - EIOINTC_COREMAP_START) >> 3; in loongarch_eiointc_write()
284 old = s->coremap[index]; in loongarch_eiointc_write()
285 s->coremap[index] = (old & ~mask) | data; in loongarch_eiointc_write()
286 data = s->coremap[index]; in loongarch_eiointc_write()
287 eiointc_update_sw_coremap(s, index * 8, data, sizeof(data), true); 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()
326 case 4: in kvm_eiointc_write()
335 spin_unlock_irqrestore(&eiointc->lock, flags); in kvm_eiointc_write()
350 u32 *data = val; in kvm_eiointc_virt_read() local
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()
425 void __user *data; in kvm_eiointc_ctrl_access() local
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()
432 if (copy_from_user(&val, data, 4)) 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[i], sizeof(u64), false); in kvm_eiointc_ctrl_access()
463 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_ctrl_access()
470 bool is_write, int *data) in kvm_eiointc_regs_access() argument
477 s = dev->kvm->arch.eiointc; in kvm_eiointc_regs_access()
478 addr = attr->attr; in kvm_eiointc_regs_access()
483 offset = (addr - EIOINTC_NODETYPE_START) / 4; in kvm_eiointc_regs_access()
484 p = s->nodetype + offset * 4; in kvm_eiointc_regs_access()
487 offset = (addr - EIOINTC_IPMAP_START) / 4; in kvm_eiointc_regs_access()
488 p = &s->ipmap + offset * 4; in kvm_eiointc_regs_access()
491 offset = (addr - EIOINTC_ENABLE_START) / 4; in kvm_eiointc_regs_access()
492 p = s->enable + offset * 4; in kvm_eiointc_regs_access()
495 offset = (addr - EIOINTC_BOUNCE_START) / 4; in kvm_eiointc_regs_access()
496 p = s->bounce + offset * 4; in kvm_eiointc_regs_access()
499 offset = (addr - EIOINTC_ISR_START) / 4; in kvm_eiointc_regs_access()
500 p = s->isr + offset * 4; 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[cpu] + offset * 4; in kvm_eiointc_regs_access()
510 offset = (addr - EIOINTC_COREMAP_START) / 4; in kvm_eiointc_regs_access()
511 p = s->coremap + offset * 4; 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()
520 memcpy(p, data, 4); in kvm_eiointc_regs_access()
522 memcpy(data, p, 4); in kvm_eiointc_regs_access()
523 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_regs_access()
530 bool is_write, int *data) in kvm_eiointc_sw_status_access() argument
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()
563 memcpy(p, data, 4); in kvm_eiointc_sw_status_access()
565 memcpy(data, p, 4); in kvm_eiointc_sw_status_access()
566 spin_unlock_irqrestore(&s->lock, flags); in kvm_eiointc_sw_status_access()
574 int ret, data; in kvm_eiointc_get_attr() local
576 switch (attr->group) { in kvm_eiointc_get_attr()
578 ret = kvm_eiointc_regs_access(dev, attr, false, &data); 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()
587 ret = kvm_eiointc_sw_status_access(dev, attr, false, &data); 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()
603 int data; in kvm_eiointc_set_attr() local
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()
612 return kvm_eiointc_regs_access(dev, attr, true, &data); 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()
617 return kvm_eiointc_sw_status_access(dev, attr, true, &data); 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",