* [linux-next:master 5531/8449] arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: sparse: incorrect type in assignment (different address spaces)
@ 2026-09-18 22:43 kernel test robot
0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2026-09-18 22:43 UTC (permalink / raw)
To: Sascha Bischoff; +Cc: oe-kbuild-all, Marc Zyngier
tree: https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git master
head: 3f2425f5b5bbbdd991ca9cdfd5502e68d8895998
commit: f45438c015291f26e99f7fe355c4c191b5750f8d [5531/8449] KVM: arm64: gic-v5: Create and manage VM and VPE tables
config: arm64-randconfig-r1307-20260918 (https://download.01.org/0day-ci/archive/20260919/202609190650.liMAzwjF-lkp@intel.com/config)
compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 7252edd9aa82ef1c570ff6694ef7f4763a8a5d2f)
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260919/202609190650.liMAzwjF-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202609190650.liMAzwjF-lkp@intel.com/
sparse warnings: (new ones prefixed by >>)
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected void [noderef] __iomem *vmd_base @@ got void *[assigned] vmd @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: expected void [noderef] __iomem *vmd_base
arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: got void *[assigned] vmd
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:497:24: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected restricted __le64 [noderef] [usertype] __iomem *vpet_base @@ got restricted __le64 [usertype] *[assigned] vpet @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:497:24: sparse: expected restricted __le64 [noderef] [usertype] __iomem *vpet_base
arch/arm64/kvm/vgic/vgic-v5-tables.c:497:24: sparse: got restricted __le64 [usertype] *[assigned] vpet
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:585:18: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const *objp @@ got restricted __le64 [noderef] [usertype] __iomem *vpet_base @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:585:18: sparse: expected void const *objp
arch/arm64/kvm/vgic/vgic-v5-tables.c:585:18: sparse: got restricted __le64 [noderef] [usertype] __iomem *vpet_base
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:586:18: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected void const *objp @@ got void [noderef] __iomem *vmd_base @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:586:18: sparse: expected void const *objp
arch/arm64/kvm/vgic/vgic-v5-tables.c:586:18: sparse: got void [noderef] __iomem *vmd_base
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:626:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected restricted __le64 [usertype] *vpet_base @@ got restricted __le64 [noderef] [usertype] __iomem *vpet_base @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:626:19: sparse: expected restricted __le64 [usertype] *vpet_base
arch/arm64/kvm/vgic/vgic-v5-tables.c:626:19: sparse: got restricted __le64 [noderef] [usertype] __iomem *vpet_base
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:638:13: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __le64 [usertype] tmp @@ got unsigned long long @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:638:13: sparse: expected restricted __le64 [usertype] tmp
arch/arm64/kvm/vgic/vgic-v5-tables.c:638:13: sparse: got unsigned long long
>> arch/arm64/kvm/vgic/vgic-v5-tables.c:641:17: sparse: sparse: cast from restricted __le64
arch/arm64/kvm/vgic/vgic-v5-tables.c:674:19: sparse: sparse: incorrect type in assignment (different address spaces) @@ expected restricted __le64 [usertype] *vpet_base @@ got restricted __le64 [noderef] [usertype] __iomem *vpet_base @@
arch/arm64/kvm/vgic/vgic-v5-tables.c:674:19: sparse: expected restricted __le64 [usertype] *vpet_base
arch/arm64/kvm/vgic/vgic-v5-tables.c:674:19: sparse: got restricted __le64 [noderef] [usertype] __iomem *vpet_base
vim +456 arch/arm64/kvm/vgic/vgic-v5-tables.c
385
386 /*
387 * Initialise an entry in the VMT based on the index of the VM.
388 *
389 * Note: We don't mark the VMTE as valid as this needs to be done by
390 * the hardware.
391 */
392 int vgic_v5_vmte_init(struct kvm *kvm)
393 {
394 size_t vmd_alloc_size, vpet_alloc_size, vped_alloc_size;
395 void *vped_base = NULL, *vmd = NULL;
396 struct vgic_v5_vm_info *vmi = NULL;
397 u64 tmp, vmte_val0 = 0, vmte_val1;
398 u32 vm_id = vgic_v5_vm_id(kvm);
399 int ret, nr_cpus, nr_vcpus;
400 bool vmi_inserted = false;
401 struct vmtl2_entry *vmte;
402 vpe_entry *vpet = NULL;
403 struct kvm_vcpu *vcpu;
404 u16 max_vpe_id = 0;
405 unsigned long i;
406
407 nr_vcpus = atomic_read(&kvm->online_vcpus);
408 if (nr_vcpus > vmt_info->max_vpes)
409 return -E2BIG;
410
411 /*
412 * If we're using two-level VMTs, L2 is allocated on demand. For linear
413 * VMTs, this is a NOP.
414 */
415 ret = vgic_v5_alloc_l2_vmt(kvm);
416 if (ret)
417 return ret;
418
419 vmte = vgic_v5_get_l2_vmte(vm_id);
420 if (IS_ERR(vmte))
421 return PTR_ERR(vmte);
422
423 /* If the entry is already valid, something went wrong */
424 scoped_guard(raw_spinlock_irqsave, &vgic_v5_irs_lock) {
425 vgic_v5_clean_inval(vmte, sizeof(*vmte));
426 if (le64_to_cpu(READ_ONCE(vmte->val[0])) & GICV5_VMTEL2E_VALID)
427 return -EINVAL;
428 }
429
430 ret = vgic_v5_reset_vmte(kvm);
431 if (ret)
432 return ret;
433
434 vmi = kzalloc_obj(*vmi);
435 if (!vmi) {
436 ret = -ENOMEM;
437 goto out_fail;
438 }
439
440 ret = xa_insert(&vm_info, vm_id, vmi, GFP_KERNEL);
441 if (ret)
442 goto out_fail;
443 vmi_inserted = true;
444
445 /* Allocate and assign the VM Descriptor, if required. */
446 if (vmt_info->vmd_size != 0) {
447 vmd_alloc_size = round_up(vmt_info->vmd_size,
448 dma_get_cache_alignment());
449 vmd = kzalloc(vmd_alloc_size, GFP_KERNEL);
450 if (!vmd) {
451 ret = -ENOMEM;
452 goto out_fail;
453 }
454
455 /* Stash the VA so we can free it later */
> 456 vmi->vmd_base = vmd;
457
458 tmp = FIELD_PREP(GICV5_VMTEL2E_VMD_ADDR,
459 virt_to_phys(vmd) >> GICV5_VMTEL2E_VMD_ADDR_SHIFT);
460 vmte_val0 = tmp;
461 }
462
463 /*
464 * Allocate and assign the VPE Table.
465 *
466 * First of all, iterate over all vcpus to find the highest VPE ID we
467 * require - we need to ensure that we have enough storage for all
468 * vcpu_id values that userspace has picked and not just the total
469 * number of vcpus. This gives us the number of VPEs required for the
470 * VM.
471 *
472 * Round up the number of VPEs to a whole power of two as we cannot
473 * describe non-powers-of-two in the VMTE field as it conveys the number
474 * of ID bits used and not the number of vPEs. IRS_IDR1.IAFFID_BITS is
475 * encoded as N - 1, so expose at least one VPE ID bit even for a
476 * single-vCPU VM to keep the views consistent.
477 */
478 kvm_for_each_vcpu(i, vcpu, kvm) {
479 u16 vpe_id = vgic_v5_vpe_id(vcpu);
480
481 if (vpe_id > max_vpe_id)
482 max_vpe_id = vpe_id;
483 }
484
485 nr_cpus = max(2UL, roundup_pow_of_two(max_vpe_id + 1));
486 vmi->vpe_id_bits = fls(nr_cpus) - 1;
487
488 vpet_alloc_size = round_up((size_t)nr_cpus * sizeof(*vpet),
489 dma_get_cache_alignment());
490 vpet = kzalloc(vpet_alloc_size, GFP_KERNEL);
491 if (!vpet) {
492 ret = -ENOMEM;
493 goto out_fail;
494 }
495
496 /* Stash the VA so we can free it later */
> 497 vmi->vpet_base = vpet;
498
499 tmp = FIELD_PREP(GICV5_VMTEL2E_VPET_ADDR,
500 virt_to_phys(vpet) >> GICV5_VMTEL2E_VPET_ADDR_SHIFT);
501 tmp |= FIELD_PREP(GICV5_VMTEL2E_VPE_ID_BITS, vmi->vpe_id_bits);
502 vmte_val1 = tmp;
503
504 /*
505 * Allocate a dense VPED array indexed by vcpu_idx. The VPET is indexed
506 * by the potentially sparse vcpu_id, but using that ID here would waste
507 * memory. Given that this is not userspace visible, we can cheat a bit
508 * and use the dense index instead. This is the ONLY place that we do
509 * this.
510 *
511 * Round the requested size up to a whole cacheline. kzalloc() gurantees
512 * natural alignment, so we ensure that the cachelines cannot be shared
513 * with unrelated slab objects. VPED and cacheline sizes are powers of
514 * two, so this also preserves the required VPED alignment when a VPED
515 * is larger than a cacheline.
516 */
517 vped_alloc_size = round_up((size_t)nr_vcpus * vmt_info->vped_size,
518 dma_get_cache_alignment());
519 vped_base = kzalloc(vped_alloc_size, GFP_KERNEL);
520 if (!vped_base) {
521 ret = -ENOMEM;
522 goto out_fail;
523 }
524 vmi->vped_base = vped_base;
525
526 if (vmd)
527 vgic_v5_clean_inval(vmd, vmd_alloc_size);
528 vgic_v5_clean_inval(vpet, vpet_alloc_size);
529 vgic_v5_clean_inval(vped_base, vped_alloc_size);
530
531 /* Publish the VMTE while serialising access to the shared VMT. */
532 scoped_guard(raw_spinlock_irqsave, &vgic_v5_irs_lock) {
533 WRITE_ONCE(vmte->val[0], cpu_to_le64(vmte_val0));
534 WRITE_ONCE(vmte->val[1], cpu_to_le64(vmte_val1));
535 vgic_v5_clean_inval(vmte, sizeof(*vmte));
536 }
537
538 kvm->arch.vgic.gicv5_vm.vmte_allocated = true;
539
540 return 0;
541
542 out_fail:
543 /* kfree(NULL) is safe so we can just kfree() at leisure */
544 kfree(vmd);
545 kfree(vpet);
546 kfree(vped_base);
547 if (vmi_inserted)
548 xa_erase(&vm_info, vm_id);
549 kfree(vmi);
550
551 vgic_v5_reset_vmte(kvm);
552
553 return ret;
554 }
555
556 /*
557 * Release the VMT Entry, freeing up any allocated data structures before
558 * zeroing the VMTE.
559 *
560 * The VMTE must be marked as invalid before it is released.
561 */
562 int vgic_v5_vmte_release(struct kvm *kvm)
563 {
564 u32 vm_id = vgic_v5_vm_id(kvm);
565 struct vgic_v5_vm_info *vmi;
566 struct vmtl2_entry *vmte;
567 int ret;
568
569 vmte = vgic_v5_get_l2_vmte(vm_id);
570 if (IS_ERR(vmte))
571 return PTR_ERR(vmte);
572
573 /* Reject if the VMTE has not been marked as invalid! */
574 scoped_guard(raw_spinlock_irqsave, &vgic_v5_irs_lock) {
575 vgic_v5_clean_inval(vmte, sizeof(*vmte));
576 if (le64_to_cpu(READ_ONCE(vmte->val[0])) & GICV5_VMTEL2E_VALID)
577 return -EINVAL;
578 }
579
580 vmi = xa_load(&vm_info, vm_id);
581 if (!vmi)
582 goto no_vmi;
583
584 kfree(vmi->vped_base);
> 585 kfree(vmi->vpet_base);
> 586 kfree(vmi->vmd_base);
587
588 xa_erase(&vm_info, vm_id);
589 kfree(vmi);
590
591 no_vmi:
592 /*
593 * If we didn't get far enough into allocating a VMTE to create the VM
594 * info structure, then we just zero the VMTE and move on. There's
595 * nothing else we can realistically do here.
596 */
597 ret = vgic_v5_reset_vmte(kvm);
598 if (ret)
599 return ret;
600
601 kvm->arch.vgic.gicv5_vm.vmte_allocated = false;
602
603 return 0;
604 }
605
606 /* Provide the preallocated VPE descriptor to the hardware via the VPE Table. */
607 int vgic_v5_vmte_alloc_vpe(struct kvm_vcpu *vcpu)
608 {
609 u32 vm_id = vgic_v5_vm_id(vcpu->kvm);
610 u16 vpe_id = vgic_v5_vpe_id(vcpu);
611 struct vgic_v5_vm_info *vmi;
612 vpe_entry tmp, *vpet_base;
613 void *vped;
614
615 /* Make sure we're not over what the hardware supports */
616 if (vpe_id >= vmt_info->max_vpes)
617 return -E2BIG;
618
619 vmi = xa_load(&vm_info, vm_id);
620 if (!vmi)
621 return -EINVAL;
622
623 if (vpe_id >= 1 << vmi->vpe_id_bits)
624 return -E2BIG;
625
> 626 vpet_base = vmi->vpet_base;
627
628 /* If the VPETE for this CPU is already valid we've gone wrong */
629 scoped_guard(raw_spinlock_irqsave, &vgic_v5_irs_lock) {
630 vgic_v5_clean_inval(&vpet_base[vpe_id], sizeof(*vpet_base));
631 if (le64_to_cpu(READ_ONCE(vpet_base[vpe_id])) & GICV5_VPE_VALID)
632 return -EBUSY;
633 }
634
635 vped = (u8 *)vmi->vped_base +
636 (size_t)vcpu->vcpu_idx * vmt_info->vped_size;
637
> 638 tmp = FIELD_PREP(GICV5_VPED_ADDR, virt_to_phys(vped) >> GICV5_VPED_ADDR_SHIFT);
639
640 scoped_guard(raw_spinlock_irqsave, &vgic_v5_irs_lock) {
> 641 WRITE_ONCE(vpet_base[vpe_id], cpu_to_le64(tmp));
642 vgic_v5_clean_inval(vpet_base + vpe_id, sizeof(vpe_entry));
643 }
644
645 return 0;
646 }
647
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-18 22:43 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-18 22:43 [linux-next:master 5531/8449] arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: sparse: incorrect type in assignment (different address spaces) kernel test robot
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.