ANDROID: drivers/arm-smmu-v3-kvm: Add dev_block_dma
When a device is assigned dev_block_dma is called to put DMA in quiescent state. Bug: 357781595 Bug: 348382247 Change-Id: Ibcf054dab9bb3e193c45887b5cb82845a1072148 Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
committed by
Treehugger Robot
parent
22a0449b96
commit
007871cbf7
@@ -169,7 +169,8 @@ static struct iommu_domain *kvm_arm_smmu_domain_alloc(unsigned type)
|
||||
*/
|
||||
if (type != IOMMU_DOMAIN_DMA &&
|
||||
type != IOMMU_DOMAIN_UNMANAGED &&
|
||||
type != IOMMU_DOMAIN_IDENTITY)
|
||||
type != IOMMU_DOMAIN_IDENTITY &&
|
||||
type != IOMMU_DOMAIN_BLOCKED)
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
||||
kvm_smmu_domain = kzalloc(sizeof(*kvm_smmu_domain), GFP_KERNEL);
|
||||
@@ -352,7 +353,7 @@ static int kvm_arm_smmu_set_dev_pasid(struct iommu_domain *domain,
|
||||
host_smmu = smmu_to_host(smmu);
|
||||
|
||||
ret = kvm_arm_smmu_detach_dev_pasid(host_smmu, master, pasid);
|
||||
if (ret)
|
||||
if (ret || (domain->type == IOMMU_DOMAIN_BLOCKED))
|
||||
return ret;
|
||||
|
||||
mutex_lock(&kvm_smmu_domain->init_mutex);
|
||||
|
||||
@@ -1550,6 +1550,31 @@ static bool smmu_dabt_device(struct hyp_arm_smmu_v3_device *smmu,
|
||||
return true;
|
||||
}
|
||||
|
||||
static int smmu_dev_block_dma(struct kvm_hyp_iommu *iommu, u32 sid, bool is_host2guest)
|
||||
{
|
||||
struct hyp_arm_smmu_v3_device *smmu = to_smmu(iommu);
|
||||
static struct arm_smmu_ste *dst;
|
||||
int ret = 0;
|
||||
|
||||
kvm_iommu_lock(iommu);
|
||||
dst = smmu_get_ste_ptr(smmu, sid);
|
||||
|
||||
/*
|
||||
* VFIO will attach the device to a blocking domain, this will make the
|
||||
* kernel driver detach the device which should be have zeroed STE.
|
||||
* So, if this is not the current state of the device, something
|
||||
* went wrong.
|
||||
* For guests, we need to do more as guests might not exit cleanly
|
||||
* and the device might be translating, so we have to actually block
|
||||
* the device and clean the STE/CD.
|
||||
*/
|
||||
if (dst->data[0])
|
||||
ret = -EINVAL;
|
||||
|
||||
kvm_iommu_unlock(iommu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool smmu_dabt_handler(struct kvm_cpu_context *host_ctxt, u64 esr, u64 addr)
|
||||
{
|
||||
struct hyp_arm_smmu_v3_device *smmu;
|
||||
@@ -1688,4 +1713,5 @@ struct kvm_iommu_ops smmu_ops = {
|
||||
.suspend = smmu_suspend,
|
||||
.resume = smmu_resume,
|
||||
.host_stage2_idmap = smmu_host_stage2_idmap,
|
||||
.dev_block_dma = smmu_dev_block_dma,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user