ANDROID: KVM: iommu: Add flags to attach_dev
There is no way to pass device specific information at attach time (to handle errata or special IOMMU configuration). Add a new argument to attach hypercalls “flags” which can be passed from the EL1 to EL2 driver to describe any driver specific information. It ‘s mandatory for devices supporting pvIOMMU, to reserve the value “0” as this is not exposed to guests and “0” would be passed. Bug: 357781595 Change-Id: I81a0b82591a0fe6d952f46025fbd95a82020c14d Signed-off-by: Mostafa Saleh <smostafa@google.com>
This commit is contained in:
committed by
Carlos Llamas
parent
2ea2a15fa1
commit
87dd5e4d38
@@ -1767,7 +1767,7 @@ static inline void kvm_iommu_sg_free(struct kvm_iommu_sg *sg, unsigned int nents
|
||||
#ifndef __KVM_NVHE_HYPERVISOR__
|
||||
int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
unsigned int endpoint, unsigned int pasid,
|
||||
unsigned int ssid_bits);
|
||||
unsigned int ssid_bits, unsigned long flags);
|
||||
int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
unsigned int endpoint, unsigned int pasid);
|
||||
int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type);
|
||||
|
||||
@@ -18,7 +18,8 @@ void kvm_iommu_reclaim_pages_atomic(void *p, u8 order);
|
||||
int kvm_iommu_alloc_domain(pkvm_handle_t domain_id, int type);
|
||||
int kvm_iommu_free_domain(pkvm_handle_t domain_id);
|
||||
int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits);
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits,
|
||||
unsigned long flags);
|
||||
int kvm_iommu_detach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
u32 endpoint_id, u32 pasid);
|
||||
size_t kvm_iommu_map_pages(pkvm_handle_t domain_id,
|
||||
@@ -56,7 +57,7 @@ struct kvm_iommu_ops {
|
||||
void (*free_domain)(struct kvm_hyp_iommu_domain *domain);
|
||||
struct kvm_hyp_iommu *(*get_iommu_by_id)(pkvm_handle_t iommu_id);
|
||||
int (*attach_dev)(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits);
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits, unsigned long flags);
|
||||
int (*detach_dev)(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
|
||||
u32 endpoint_id, u32 pasid);
|
||||
int (*map_pages)(struct kvm_hyp_iommu_domain *domain, unsigned long iova,
|
||||
|
||||
@@ -1724,9 +1724,10 @@ static void handle___pkvm_host_iommu_attach_dev(struct kvm_cpu_context *host_ctx
|
||||
DECLARE_REG(unsigned int, endpoint, host_ctxt, 3);
|
||||
DECLARE_REG(unsigned int, pasid, host_ctxt, 4);
|
||||
DECLARE_REG(unsigned int, pasid_bits, host_ctxt, 5);
|
||||
DECLARE_REG(unsigned long, flags, host_ctxt, 6);
|
||||
|
||||
ret = kvm_iommu_attach_dev(iommu, domain, endpoint,
|
||||
pasid, pasid_bits);
|
||||
pasid, pasid_bits, flags);
|
||||
hyp_reqs_smccc_encode(ret, host_ctxt, this_cpu_ptr(&host_hyp_reqs));
|
||||
}
|
||||
|
||||
|
||||
@@ -387,7 +387,8 @@ int kvm_iommu_force_free_domain(pkvm_handle_t domain_id, struct pkvm_hyp_vm *vm)
|
||||
}
|
||||
|
||||
int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits)
|
||||
u32 endpoint_id, u32 pasid, u32 pasid_bits,
|
||||
unsigned long flags)
|
||||
{
|
||||
int ret;
|
||||
struct kvm_hyp_iommu *iommu;
|
||||
@@ -417,7 +418,7 @@ int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = kvm_iommu_ops->attach_dev(iommu, domain, endpoint_id, pasid, pasid_bits);
|
||||
ret = kvm_iommu_ops->attach_dev(iommu, domain, endpoint_id, pasid, pasid_bits, flags);
|
||||
if (ret)
|
||||
domain_put(domain);
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ static bool pkvm_guest_iommu_attach_dev(struct pkvm_hyp_vcpu *hyp_vcpu, u64 *exi
|
||||
iommu_id = route.iommu;
|
||||
sid = route.sid;
|
||||
|
||||
ret = kvm_iommu_attach_dev(iommu_id, domain_id, sid, pasid, pasid_bits);
|
||||
ret = kvm_iommu_attach_dev(iommu_id, domain_id, sid, pasid, pasid_bits, 0);
|
||||
if (ret == -ENOMEM) {
|
||||
/*
|
||||
* The driver will request memory when returning -ENOMEM, so go back to host to
|
||||
|
||||
@@ -209,10 +209,10 @@ void kvm_iommu_guest_free_mc(struct kvm_hyp_memcache *mc)
|
||||
/* Hypercall abstractions exposed to kernel IOMMU drivers */
|
||||
int kvm_iommu_attach_dev(pkvm_handle_t iommu_id, pkvm_handle_t domain_id,
|
||||
unsigned int endpoint, unsigned int pasid,
|
||||
unsigned int ssid_bits)
|
||||
unsigned int ssid_bits, unsigned long flags)
|
||||
{
|
||||
return kvm_call_hyp_nvhe_mc(__pkvm_host_iommu_attach_dev, iommu_id, domain_id,
|
||||
endpoint, pasid, ssid_bits);
|
||||
endpoint, pasid, ssid_bits, flags);
|
||||
}
|
||||
EXPORT_SYMBOL(kvm_iommu_attach_dev);
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@ static int kvm_arm_smmu_set_dev_pasid(struct iommu_domain *domain,
|
||||
int sid = fwspec->ids[i];
|
||||
|
||||
ret = kvm_iommu_attach_dev(host_smmu->id, kvm_smmu_domain->id,
|
||||
sid, pasid, master->ssid_bits);
|
||||
sid, pasid, master->ssid_bits, 0);
|
||||
if (ret) {
|
||||
dev_err(smmu->dev, "cannot attach device %s (0x%x): %d\n",
|
||||
dev_name(dev), sid, ret);
|
||||
|
||||
@@ -1246,7 +1246,7 @@ static int smmu_fix_up_domains(struct hyp_arm_smmu_v3_device *smmu,
|
||||
}
|
||||
|
||||
static int smmu_attach_dev(struct kvm_hyp_iommu *iommu, struct kvm_hyp_iommu_domain *domain,
|
||||
u32 sid, u32 pasid, u32 pasid_bits)
|
||||
u32 sid, u32 pasid, u32 pasid_bits, unsigned long flags)
|
||||
{
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
Reference in New Issue
Block a user