[kvm:queue 32/111] arch/x86/kvm/svm.c:6231:60: sparse: dereference of noderef expression

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



tree:   https://git.kernel.org/pub/scm/virt/kvm/kvm.git queue
head:   da0fb9f3d73e7ab266d72a9b216ce0f3833c1e83
commit: 24f41fb23a39bc2b6f190dcef35a5813a4bf183a [32/111] KVM: SVM: Add support for SEV DEBUG_DECRYPT command
reproduce:
        # apt-get install sparse
        git checkout 24f41fb23a39bc2b6f190dcef35a5813a4bf183a
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

   arch/x86/kvm/svm.c:6073:22: sparse: incorrect type in argument 1 (different base types) @@ expected void const volatile @@ got unsigned long lonvoid const volatile @@
   arch/x86/kvm/svm.c:6073:22: expected void const volatile
   arch/x86/kvm/svm.c:6073:22: got unsigned long long uaddr
   arch/x86/include/asm/paravirt.h:149:9: sparse: cast truncates bits from constant value (100000000 becomes 0)
   arch/x86/include/asm/paravirt.h:149:9: sparse: cast truncates bits from constant value (100000000 becomes 0)
>> arch/x86/kvm/svm.c:6231:60: sparse: dereference of noderef expression

vim +6231 arch/x86/kvm/svm.c

  6044	
  6045	static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp)
  6046	{
  6047		struct kvm_sev_info *sev = &kvm->arch.sev_info;
  6048		struct sev_data_launch_measure *data;
  6049		struct kvm_sev_launch_measure params;
  6050		void *blob = NULL;
  6051		int ret;
  6052	
  6053		if (!sev_guest(kvm))
  6054			return -ENOTTY;
  6055	
  6056		if (copy_from_user(&params, (void __user *)(uintptr_t)argp->data, sizeof(params)))
  6057			return -EFAULT;
  6058	
  6059		data = kzalloc(sizeof(*data), GFP_KERNEL);
  6060		if (!data)
  6061			return -ENOMEM;
  6062	
  6063		/* User wants to query the blob length */
  6064		if (!params.len)
  6065			goto cmd;
  6066	
  6067		if (params.uaddr) {
  6068			if (params.len > SEV_FW_BLOB_MAX_SIZE) {
  6069				ret = -EINVAL;
  6070				goto e_free;
  6071			}
  6072	
> 6073			if (!access_ok(VERIFY_WRITE, params.uaddr, params.len)) {
  6074				ret = -EFAULT;
  6075				goto e_free;
  6076			}
  6077	
  6078			ret = -ENOMEM;
  6079			blob = kmalloc(params.len, GFP_KERNEL);
  6080			if (!blob)
  6081				goto e_free;
  6082	
  6083			data->address = __psp_pa(blob);
  6084			data->len = params.len;
  6085		}
  6086	
  6087	cmd:
  6088		data->handle = sev->handle;
  6089		ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_MEASURE, data, &argp->error);
  6090	
  6091		/*
  6092		 * If we query the session length, FW responded with expected data.
  6093		 */
  6094		if (!params.len)
  6095			goto done;
  6096	
  6097		if (ret)
  6098			goto e_free_blob;
  6099	
  6100		if (blob) {
  6101			if (copy_to_user((void __user *)(uintptr_t)params.uaddr, blob, params.len))
  6102				ret = -EFAULT;
  6103		}
  6104	
  6105	done:
  6106		params.len = data->len;
  6107		if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
  6108			ret = -EFAULT;
  6109	e_free_blob:
  6110		kfree(blob);
  6111	e_free:
  6112		kfree(data);
  6113		return ret;
  6114	}
  6115	
  6116	static int sev_launch_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
  6117	{
  6118		struct kvm_sev_info *sev = &kvm->arch.sev_info;
  6119		struct sev_data_launch_finish *data;
  6120		int ret;
  6121	
  6122		if (!sev_guest(kvm))
  6123			return -ENOTTY;
  6124	
  6125		data = kzalloc(sizeof(*data), GFP_KERNEL);
  6126		if (!data)
  6127			return -ENOMEM;
  6128	
  6129		data->handle = sev->handle;
  6130		ret = sev_issue_cmd(kvm, SEV_CMD_LAUNCH_FINISH, data, &argp->error);
  6131	
  6132		kfree(data);
  6133		return ret;
  6134	}
  6135	
  6136	static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp)
  6137	{
  6138		struct kvm_sev_info *sev = &kvm->arch.sev_info;
  6139		struct kvm_sev_guest_status params;
  6140		struct sev_data_guest_status *data;
  6141		int ret;
  6142	
  6143		if (!sev_guest(kvm))
  6144			return -ENOTTY;
  6145	
  6146		data = kzalloc(sizeof(*data), GFP_KERNEL);
  6147		if (!data)
  6148			return -ENOMEM;
  6149	
  6150		data->handle = sev->handle;
  6151		ret = sev_issue_cmd(kvm, SEV_CMD_GUEST_STATUS, data, &argp->error);
  6152		if (ret)
  6153			goto e_free;
  6154	
  6155		params.policy = data->policy;
  6156		params.state = data->state;
  6157		params.handle = data->handle;
  6158	
  6159		if (copy_to_user((void __user *)(uintptr_t)argp->data, &params, sizeof(params)))
  6160			ret = -EFAULT;
  6161	e_free:
  6162		kfree(data);
  6163		return ret;
  6164	}
  6165	
  6166	static int __sev_issue_dbg_cmd(struct kvm *kvm, unsigned long src,
  6167				       unsigned long dst, int size,
  6168				       int *error, bool enc)
  6169	{
  6170		struct kvm_sev_info *sev = &kvm->arch.sev_info;
  6171		struct sev_data_dbg *data;
  6172		int ret;
  6173	
  6174		data = kzalloc(sizeof(*data), GFP_KERNEL);
  6175		if (!data)
  6176			return -ENOMEM;
  6177	
  6178		data->handle = sev->handle;
  6179		data->dst_addr = dst;
  6180		data->src_addr = src;
  6181		data->len = size;
  6182	
  6183		ret = sev_issue_cmd(kvm,
  6184				    enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT,
  6185				    data, error);
  6186		kfree(data);
  6187		return ret;
  6188	}
  6189	
  6190	static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long src_paddr,
  6191				     unsigned long dst_paddr, int sz, int *err)
  6192	{
  6193		int offset;
  6194	
  6195		/*
  6196		 * Its safe to read more than we are asked, caller should ensure that
  6197		 * destination has enough space.
  6198		 */
  6199		src_paddr = round_down(src_paddr, 16);
  6200		offset = src_paddr & 15;
  6201		sz = round_up(sz + offset, 16);
  6202	
  6203		return __sev_issue_dbg_cmd(kvm, src_paddr, dst_paddr, sz, err, false);
  6204	}
  6205	
  6206	static int __sev_dbg_decrypt_user(struct kvm *kvm, unsigned long paddr,
  6207					  unsigned long __user dst_uaddr,
  6208					  unsigned long dst_paddr,
  6209					  int size, int *err)
  6210	{
  6211		struct page *tpage = NULL;
  6212		int ret, offset;
  6213	
  6214		/* if inputs are not 16-byte then use intermediate buffer */
  6215		if (!IS_ALIGNED(dst_paddr, 16) ||
  6216		    !IS_ALIGNED(paddr,     16) ||
  6217		    !IS_ALIGNED(size,      16)) {
  6218			tpage = (void *)alloc_page(GFP_KERNEL);
  6219			if (!tpage)
  6220				return -ENOMEM;
  6221	
  6222			dst_paddr = __sme_page_pa(tpage);
  6223		}
  6224	
  6225		ret = __sev_dbg_decrypt(kvm, paddr, dst_paddr, size, err);
  6226		if (ret)
  6227			goto e_free;
  6228	
  6229		if (tpage) {
  6230			offset = paddr & 15;
> 6231			if (copy_to_user((void __user *)(uintptr_t)dst_uaddr,
  6232					 page_address(tpage) + offset, size))
  6233				ret = -EFAULT;
  6234		}
  6235	
  6236	e_free:
  6237		if (tpage)
  6238			__free_page(tpage);
  6239	
  6240		return ret;
  6241	}
  6242	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux