All of lore.kernel.org
 help / color / mirror / Atom feed
From: kernel test robot <lkp@intel.com>
To: Sascha Bischoff <Sascha.Bischoff@arm.com>
Cc: oe-kbuild-all@lists.linux.dev, Marc Zyngier <maz@kernel.org>
Subject: [linux-next:master 5531/8449] arch/arm64/kvm/vgic/vgic-v5-tables.c:456:31: sparse: sparse: incorrect type in assignment (different address spaces)
Date: Sat, 19 Sep 2026 06:43:29 +0800	[thread overview]
Message-ID: <202609190650.liMAzwjF-lkp@intel.com> (raw)

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

                 reply	other threads:[~2026-09-18 22:43 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202609190650.liMAzwjF-lkp@intel.com \
    --to=lkp@intel.com \
    --cc=Sascha.Bischoff@arm.com \
    --cc=maz@kernel.org \
    --cc=oe-kbuild-all@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.