Commit a8078c65 authored by yangxiangkai's avatar yangxiangkai
Browse files

virtcca feature: bind the kvm handle of cvm with smmu domain

virtcca inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAQON6



--------------------------------

VirtCCA Coda Feature:
Bind the kvm handle of cvm with smmu domain

Signed-off-by: default avatarXiangkai Yang <yangxiangkai@huawei.com>
Signed-off-by: default avatarJunbin Li <lijunbin4@huawei.com>
---
parent 3985ab2b
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 */
#include <linux/kvm_host.h>
#include <linux/kvm.h>
#include <linux/vfio.h>
#include <asm/kvm_tmi.h>
#include <asm/kvm_pgtable.h>
#include <asm/kvm_emulate.h>
@@ -13,6 +14,8 @@
#include <kvm/arm_hypercalls.h>
#include <kvm/arm_psci.h>

#include "../virt/kvm/vfio.h"

/* Protects access to cvm_vmid_bitmap */
static DEFINE_SPINLOCK(cvm_vmid_lock);
static unsigned long *cvm_vmid_bitmap;
@@ -852,3 +855,38 @@ int kvm_init_cvm_vm(struct kvm *kvm)

	return 0;
}

/*
 * Coda (Confidential device assignment) feature
 * enable devices to pass directly to confidential virtual machines
 */

/**
 * cvm_arm_smmu_domain_set_kvm - Associate SMMU domain with CVM
 * @group: Iommu group
 *
 * Returns:
 * %0 if smmu_domain has been associate cvm or associate cvm successfully
 * %-ENXIO if the iommu group does not have smmu domain
 */
int cvm_arm_smmu_domain_set_kvm(void *group)
{
	struct arm_smmu_domain *arm_smmu_domain = NULL;
	struct iommu_domain *domain;
	struct kvm *kvm;

	domain = virtcca_iommu_group_get_domain((struct iommu_group *)group);
	if (!domain)
		return -ENXIO;

	arm_smmu_domain = to_smmu_domain(domain);
	if (arm_smmu_domain->kvm)
		return 0;

	kvm = virtcca_arm_smmu_get_kvm(arm_smmu_domain);
	if (kvm && kvm_is_virtcca_cvm(kvm))
		arm_smmu_domain->kvm = kvm;

	return 0;
}
+10 −0
Original line number Diff line number Diff line
@@ -2498,6 +2498,16 @@ int virtcca_attach_secure_dev(struct iommu_domain *domain, struct iommu_group *g
	return ret;
}
EXPORT_SYMBOL_GPL(virtcca_attach_secure_dev);

/* Obtain domain information through iommu group */
struct iommu_domain *virtcca_iommu_group_get_domain(struct iommu_group *iommu_group)
{
	if (iommu_group)
		return iommu_group->domain;

	return NULL;
}
EXPORT_SYMBOL_GPL(virtcca_iommu_group_get_domain);
#endif

int iommu_map(struct iommu_domain *domain, unsigned long iova,
+31 −0
Original line number Diff line number Diff line
@@ -957,3 +957,34 @@ void vfio_group_cleanup(void)
	vfio.class = NULL;
	vfio_container_cleanup();
}

#ifdef CONFIG_HISI_VIRTCCA_HOST
/**
 * virtcca_vfio_file_iommu_group - Return the struct iommu_group for the vfio group file
 * @file: VFIO group file
 *
 * The returned iommu_group is valid as long as a ref is held on the file. This
 * returns a reference on the group. This function is deprecated, only the SPAPR
 * path in kvm should call it.
 */
struct iommu_group *virtcca_vfio_file_iommu_group(struct file *file)
{
	struct vfio_group *group = vfio_group_from_file(file);
	struct iommu_group *iommu_group = NULL;

	if (!IS_ENABLED(CONFIG_HISI_VIRTCCA_HOST))
		return NULL;

	if (!group)
		return NULL;

	mutex_lock(&group->group_lock);
	if (group->iommu_group) {
		iommu_group = group->iommu_group;
		iommu_group_ref_get(iommu_group);
	}
	mutex_unlock(&group->group_lock);
	return iommu_group;
}
EXPORT_SYMBOL_GPL(virtcca_vfio_file_iommu_group);
#endif
+1 −0
Original line number Diff line number Diff line
@@ -1766,5 +1766,6 @@ static inline void iopf_group_response(struct iopf_group *group,
#ifdef CONFIG_HISI_VIRTCCA_HOST
int virtcca_attach_secure_dev(struct iommu_domain *domain, struct iommu_group *group);
int virtcca_smmu_secure_dev_operator(struct iommu_domain *domain, struct device *dev);
struct iommu_domain *virtcca_iommu_group_get_domain(struct iommu_group *iommu_group);
#endif
#endif /* __LINUX_IOMMU_H */
+3 −0
Original line number Diff line number Diff line
@@ -290,6 +290,9 @@ void vfio_combine_iova_ranges(struct rb_root_cached *root, u32 cur_nodes,
 * External user API
 */
struct iommu_group *vfio_file_iommu_group(struct file *file);
#ifdef CONFIG_HISI_VIRTCCA_HOST
struct iommu_group *virtcca_vfio_file_iommu_group(struct file *file);
#endif

#if IS_ENABLED(CONFIG_VFIO_GROUP)
bool vfio_file_is_group(struct file *file);
Loading