ANDROID: iommu/arm-smmu-v3-kvm: Support block_dma for guests
Unlike the host, where block_dma would be called after VFIO has blocked the device, the guest can die at any moment and the hypervisor have to clean after it, so in case of block_dma the hypervisor would need to handle live devices and free their resources. Bug: 357781595 Bug: 348382247 Bug: 236685427 Change-Id: I8be4ade52d0055e5fc490c28813f54b8d03998c9 Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
7a4cc58922
commit
3ab3693c96
@@ -1564,8 +1564,28 @@ static int smmu_dev_block_dma(struct kvm_hyp_iommu *iommu, u32 sid, bool is_host
|
||||
* 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;
|
||||
if (dst->data[0]) {
|
||||
if (is_host2guest) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
int i = 0;
|
||||
u32 cfg = FIELD_GET(STRTAB_STE_0_CFG, dst->data[0]);
|
||||
|
||||
if (cfg == STRTAB_STE_0_CFG_S1_TRANS) {
|
||||
size_t nr_entries, cd_sz;
|
||||
u64 cd_table;
|
||||
|
||||
cd_table = (dst->data[0] & STRTAB_STE_0_S1CTXPTR_MASK);
|
||||
nr_entries = 1 << FIELD_GET(STRTAB_STE_0_S1CDMAX, dst->data[0]);
|
||||
cd_sz = (1 << nr_entries) * (CTXDESC_CD_DWORDS << 3);
|
||||
kvm_iommu_reclaim_pages(hyp_phys_to_virt(cd_table), get_order(cd_sz));
|
||||
}
|
||||
/* zap zippity zop. */
|
||||
for (i = 0; i < STRTAB_STE_DWORDS; i++)
|
||||
dst->data[i] = 0;
|
||||
ret = smmu_sync_ste(smmu, sid);
|
||||
}
|
||||
}
|
||||
|
||||
kvm_iommu_unlock(iommu);
|
||||
return ret;
|
||||
|
||||
Reference in New Issue
Block a user