Lines Matching +full:hart +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
11 #include <linux/irqchip/riscv-imsic.h>
19 struct kvm *kvm = dev->kvm; in aia_create()
23 return -EEXIST; in aia_create()
25 ret = -EBUSY; in aia_create()
30 if (vcpu->arch.ran_atleast_once) in aia_create()
35 kvm->arch.aia.in_kernel = true; in aia_create()
50 struct kvm_aia *aia = &kvm->arch.aia; in aia_config()
54 return -EBUSY; in aia_config()
66 * supported on host with non-zero guest in aia_config()
67 * external interrupts (i.e. non-zero in aia_config()
68 * VS-level IMSIC pages). in aia_config()
71 return -EINVAL; in aia_config()
74 return -EINVAL; in aia_config()
76 aia->mode = *nr; in aia_config()
78 *nr = aia->mode; in aia_config()
87 return -EINVAL; in aia_config()
88 aia->nr_ids = *nr; in aia_config()
90 *nr = aia->nr_ids; in aia_config()
96 return -EINVAL; in aia_config()
97 aia->nr_sources = *nr; in aia_config()
99 *nr = aia->nr_sources; in aia_config()
104 return -EINVAL; in aia_config()
105 aia->nr_group_bits = *nr; in aia_config()
107 *nr = aia->nr_group_bits; in aia_config()
113 return -EINVAL; in aia_config()
114 aia->nr_group_shift = *nr; in aia_config()
116 *nr = aia->nr_group_shift; in aia_config()
121 return -EINVAL; in aia_config()
122 aia->nr_hart_bits = *nr; in aia_config()
124 *nr = aia->nr_hart_bits; in aia_config()
129 return -EINVAL; in aia_config()
130 aia->nr_guest_bits = *nr; in aia_config()
132 *nr = aia->nr_guest_bits; in aia_config()
135 return -ENXIO; in aia_config()
143 struct kvm_aia *aia = &kvm->arch.aia; in aia_aplic_addr()
148 return -EBUSY; in aia_aplic_addr()
150 if (*addr & (KVM_DEV_RISCV_APLIC_ALIGN - 1)) in aia_aplic_addr()
151 return -EINVAL; in aia_aplic_addr()
153 aia->aplic_addr = *addr; in aia_aplic_addr()
155 *addr = aia->aplic_addr; in aia_aplic_addr()
168 return -EINVAL; in aia_imsic_addr()
169 vcpu_aia = &vcpu->arch.aia_context; in aia_imsic_addr()
174 return -EBUSY; in aia_imsic_addr()
176 if (*addr & (KVM_DEV_RISCV_IMSIC_ALIGN - 1)) in aia_imsic_addr()
177 return -EINVAL; in aia_imsic_addr()
180 mutex_lock(&vcpu->mutex); in aia_imsic_addr()
182 vcpu_aia->imsic_addr = *addr; in aia_imsic_addr()
184 *addr = vcpu_aia->imsic_addr; in aia_imsic_addr()
185 mutex_unlock(&vcpu->mutex); in aia_imsic_addr()
195 h = aia->nr_hart_bits + aia->nr_guest_bits + in aia_imsic_ppn()
196 IMSIC_MMIO_PAGE_SHIFT - 1; in aia_imsic_ppn()
199 if (aia->nr_group_bits) { in aia_imsic_ppn()
200 h = aia->nr_group_bits + aia->nr_group_shift - 1; in aia_imsic_ppn()
201 l = aia->nr_group_shift; in aia_imsic_ppn()
210 u32 hart = 0, group = 0; in aia_imsic_hart_index() local
212 if (aia->nr_hart_bits) in aia_imsic_hart_index()
213 hart = (addr >> (aia->nr_guest_bits + IMSIC_MMIO_PAGE_SHIFT)) & in aia_imsic_hart_index()
214 GENMASK_ULL(aia->nr_hart_bits - 1, 0); in aia_imsic_hart_index()
215 if (aia->nr_group_bits) in aia_imsic_hart_index()
216 group = (addr >> aia->nr_group_shift) & in aia_imsic_hart_index()
217 GENMASK_ULL(aia->nr_group_bits - 1, 0); in aia_imsic_hart_index()
219 return (group << aia->nr_hart_bits) | hart; in aia_imsic_hart_index()
228 struct kvm_aia *aia = &kvm->arch.aia; in aia_init()
233 return -EBUSY; in aia_init()
236 if (kvm->created_vcpus != atomic_read(&kvm->online_vcpus)) in aia_init()
237 return -EBUSY; in aia_init()
240 if (aia->nr_ids < aia->nr_sources) in aia_init()
241 return -EINVAL; in aia_init()
243 /* APLIC base is required for non-zero number of sources */ in aia_init()
244 if (aia->nr_sources && aia->aplic_addr == KVM_RISCV_AIA_UNDEF_ADDR) in aia_init()
245 return -EINVAL; in aia_init()
254 vaia = &vcpu->arch.aia_context; in aia_init()
257 if (vaia->imsic_addr == KVM_RISCV_AIA_UNDEF_ADDR) { in aia_init()
258 ret = -EINVAL; in aia_init()
264 base_ppn = aia_imsic_ppn(aia, vaia->imsic_addr); in aia_init()
265 if (base_ppn != aia_imsic_ppn(aia, vaia->imsic_addr)) { in aia_init()
266 ret = -EINVAL; in aia_init()
270 /* Update HART index of the IMSIC based on IMSIC base */ in aia_init()
271 vaia->hart_index = aia_imsic_hart_index(aia, in aia_init()
272 vaia->imsic_addr); in aia_init()
281 kvm->arch.aia.initialized = true; in aia_init()
286 for (i = idx - 1; i >= 0; i--) { in aia_init()
300 int nr_vcpus, r = -ENXIO; in aia_set_attr()
301 unsigned long v, type = (unsigned long)attr->attr; in aia_set_attr()
302 void __user *uaddr = (void __user *)(long)attr->addr; in aia_set_attr()
304 switch (attr->group) { in aia_set_attr()
307 return -EFAULT; in aia_set_attr()
309 mutex_lock(&dev->kvm->lock); in aia_set_attr()
310 r = aia_config(dev->kvm, type, &nr, true); in aia_set_attr()
311 mutex_unlock(&dev->kvm->lock); in aia_set_attr()
317 return -EFAULT; in aia_set_attr()
319 nr_vcpus = atomic_read(&dev->kvm->online_vcpus); in aia_set_attr()
320 mutex_lock(&dev->kvm->lock); in aia_set_attr()
322 r = aia_aplic_addr(dev->kvm, &addr, true); in aia_set_attr()
324 r = aia_imsic_addr(dev->kvm, &addr, in aia_set_attr()
325 type - KVM_DEV_RISCV_AIA_ADDR_IMSIC(0), true); in aia_set_attr()
326 mutex_unlock(&dev->kvm->lock); in aia_set_attr()
333 mutex_lock(&dev->kvm->lock); in aia_set_attr()
334 r = aia_init(dev->kvm); in aia_set_attr()
335 mutex_unlock(&dev->kvm->lock); in aia_set_attr()
342 return -EFAULT; in aia_set_attr()
344 mutex_lock(&dev->kvm->lock); in aia_set_attr()
345 r = kvm_riscv_aia_aplic_set_attr(dev->kvm, type, nr); in aia_set_attr()
346 mutex_unlock(&dev->kvm->lock); in aia_set_attr()
351 return -EFAULT; in aia_set_attr()
353 mutex_lock(&dev->kvm->lock); in aia_set_attr()
354 r = kvm_riscv_aia_imsic_rw_attr(dev->kvm, type, true, &v); in aia_set_attr()
355 mutex_unlock(&dev->kvm->lock); in aia_set_attr()
367 int nr_vcpus, r = -ENXIO; in aia_get_attr()
368 void __user *uaddr = (void __user *)(long)attr->addr; in aia_get_attr()
369 unsigned long v, type = (unsigned long)attr->attr; in aia_get_attr()
371 switch (attr->group) { in aia_get_attr()
374 return -EFAULT; in aia_get_attr()
376 mutex_lock(&dev->kvm->lock); in aia_get_attr()
377 r = aia_config(dev->kvm, type, &nr, false); in aia_get_attr()
378 mutex_unlock(&dev->kvm->lock); in aia_get_attr()
383 return -EFAULT; in aia_get_attr()
388 return -EFAULT; in aia_get_attr()
390 nr_vcpus = atomic_read(&dev->kvm->online_vcpus); in aia_get_attr()
391 mutex_lock(&dev->kvm->lock); in aia_get_attr()
393 r = aia_aplic_addr(dev->kvm, &addr, false); in aia_get_attr()
395 r = aia_imsic_addr(dev->kvm, &addr, in aia_get_attr()
396 type - KVM_DEV_RISCV_AIA_ADDR_IMSIC(0), false); in aia_get_attr()
397 mutex_unlock(&dev->kvm->lock); in aia_get_attr()
402 return -EFAULT; in aia_get_attr()
407 return -EFAULT; in aia_get_attr()
409 mutex_lock(&dev->kvm->lock); in aia_get_attr()
410 r = kvm_riscv_aia_aplic_get_attr(dev->kvm, type, &nr); in aia_get_attr()
411 mutex_unlock(&dev->kvm->lock); in aia_get_attr()
416 return -EFAULT; in aia_get_attr()
421 return -EFAULT; in aia_get_attr()
423 mutex_lock(&dev->kvm->lock); in aia_get_attr()
424 r = kvm_riscv_aia_imsic_rw_attr(dev->kvm, type, false, &v); in aia_get_attr()
425 mutex_unlock(&dev->kvm->lock); in aia_get_attr()
430 return -EFAULT; in aia_get_attr()
442 switch (attr->group) { in aia_has_attr()
444 switch (attr->attr) { in aia_has_attr()
456 nr_vcpus = atomic_read(&dev->kvm->online_vcpus); in aia_has_attr()
457 if (attr->attr == KVM_DEV_RISCV_AIA_ADDR_APLIC) in aia_has_attr()
459 else if (attr->attr < KVM_DEV_RISCV_AIA_ADDR_IMSIC(nr_vcpus)) in aia_has_attr()
463 switch (attr->attr) { in aia_has_attr()
469 return kvm_riscv_aia_aplic_has_attr(dev->kvm, attr->attr); in aia_has_attr()
471 return kvm_riscv_aia_imsic_has_attr(dev->kvm, attr->attr); in aia_has_attr()
474 return -ENXIO; in aia_has_attr()
478 .name = "kvm-riscv-aia",
489 if (!kvm_riscv_aia_initialized(vcpu->kvm)) in kvm_riscv_vcpu_aia_update()
490 return 1; in kvm_riscv_vcpu_aia_update()
498 struct kvm_vcpu_aia_csr *csr = &vcpu->arch.aia_context.guest_csr; in kvm_riscv_vcpu_aia_reset()
505 if (!kvm_riscv_aia_initialized(vcpu->kvm)) in kvm_riscv_vcpu_aia_reset()
514 struct kvm_vcpu_aia *vaia = &vcpu->arch.aia_context; in kvm_riscv_vcpu_aia_init()
521 * will be done after AIA device is initialized by the user-space. in kvm_riscv_vcpu_aia_init()
527 vaia->imsic_addr = KVM_RISCV_AIA_UNDEF_ADDR; in kvm_riscv_vcpu_aia_init()
528 vaia->hart_index = vcpu->vcpu_idx; in kvm_riscv_vcpu_aia_init()
534 if (!kvm_riscv_aia_initialized(vcpu->kvm)) in kvm_riscv_vcpu_aia_deinit()
549 return -EBUSY; in kvm_riscv_aia_inject_msi_by_id()
553 if (vcpu->arch.aia_context.hart_index == hart_index) in kvm_riscv_aia_inject_msi_by_id()
567 u32 g, toff, iid = msi->data; in kvm_riscv_aia_inject_msi()
568 struct kvm_aia *aia = &kvm->arch.aia; in kvm_riscv_aia_inject_msi()
569 gpa_t target = (((gpa_t)msi->address_hi) << 32) | msi->address_lo; in kvm_riscv_aia_inject_msi()
573 return -EBUSY; in kvm_riscv_aia_inject_msi()
579 g = tppn & (BIT(aia->nr_guest_bits) - 1); in kvm_riscv_aia_inject_msi()
580 tppn &= ~((gpa_t)(BIT(aia->nr_guest_bits) - 1)); in kvm_riscv_aia_inject_msi()
584 ippn = vcpu->arch.aia_context.imsic_addr >> in kvm_riscv_aia_inject_msi()
587 toff = target & (IMSIC_MMIO_PAGE_SZ - 1); in kvm_riscv_aia_inject_msi()
600 return -EBUSY; in kvm_riscv_aia_inject_irq()
608 struct kvm_aia *aia = &kvm->arch.aia; in kvm_riscv_aia_init_vm()
615 * will be done after AIA device is initialized by the user-space. in kvm_riscv_aia_init_vm()
621 aia->mode = (kvm_riscv_aia_nr_hgei) ? in kvm_riscv_aia_init_vm()
623 aia->nr_ids = kvm_riscv_aia_max_ids - 1; in kvm_riscv_aia_init_vm()
624 aia->nr_sources = 0; in kvm_riscv_aia_init_vm()
625 aia->nr_group_bits = 0; in kvm_riscv_aia_init_vm()
626 aia->nr_group_shift = KVM_DEV_RISCV_AIA_GROUP_SHIFT_MIN; in kvm_riscv_aia_init_vm()
627 aia->nr_hart_bits = 0; in kvm_riscv_aia_init_vm()
628 aia->nr_guest_bits = 0; in kvm_riscv_aia_init_vm()
629 aia->aplic_addr = KVM_RISCV_AIA_UNDEF_ADDR; in kvm_riscv_aia_init_vm()