iommu/arm-smmu: Migrate SCM IO calls in arm-smmu

Migrate SCM IO read calls in the smmu driver to use new SCM driver.
Add support for io-pgtable-msm-secure map and unmap in SCM driver.

Change-Id: If1ce054b9cfcfdcdab3aecc6752fcd4765197a05
Signed-off-by: Siddharth Gupta <sidgup@codeaurora.org>
Signed-off-by: Elliot Berman <eberman@codeaurora.org>
This commit is contained in:
Siddharth Gupta 2019-09-11 18:04:07 -07:00 • committed by Elliot Berman
commit 050d2dca67
5 changed files with 97 additions and 6 deletions

View file

@ -952,6 +952,58 @@ int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size,
return ret;
}
int __qcom_scm_iommu_secure_map(struct device *dev, phys_addr_t sg_list_addr,
size_t num_sg, size_t sg_block_size, u64 sec_id,
int cbndx, unsigned long iova, size_t total_len)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_MP,
.cmd = QCOM_SCM_MP_IOMMU_SECURE_MAP2_FLAT,
.owner = ARM_SMCCC_OWNER_SIP
};
desc.args[0] = sg_list_addr;
desc.args[1] = num_sg;
desc.args[2] = sg_block_size;
desc.args[3] = sec_id;
desc.args[4] = cbndx;
desc.args[5] = iova;
desc.args[6] = total_len;
desc.args[7] = 0;
desc.arginfo = QCOM_SCM_ARGS(8, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_VAL,
QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL, QCOM_SCM_VAL,
QCOM_SCM_VAL);
ret = qcom_scm_call(dev, &desc);
return ret ? : desc.res[0];
}
int __qcom_scm_iommu_secure_unmap(struct device *dev, u64 sec_id, int cbndx,
unsigned long iova, size_t total_len)
{
int ret;
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_MP,
.cmd = QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT,
.owner = ARM_SMCCC_OWNER_SIP
};
desc.args[0] = sec_id;
desc.args[1] = cbndx;
desc.args[2] = iova;
desc.args[3] = total_len;
desc.args[4] = QCOM_SCM_IOMMU_TLBINVAL_FLAG;
desc.arginfo = QCOM_SCM_ARGS(5);
ret = qcom_scm_call(dev, &desc);
return ret ? : desc.res[0];
}
int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
size_t mem_sz, phys_addr_t src, size_t src_sz,
phys_addr_t dest, size_t dest_sz)

View file

@ -358,6 +358,23 @@ int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg,
size_t sg_block_size, u64 sec_id, int cbndx,
unsigned long iova, size_t total_len)
{
return __qcom_scm_iommu_secure_map(__scm->dev, sg_list_addr, num_sg,
sg_block_size, sec_id, cbndx, iova, total_len);
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_map);
int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx, unsigned long iova,
size_t total_len)
{
return __qcom_scm_iommu_secure_unmap(__scm->dev, sec_id, cbndx, iova,
total_len);
}
EXPORT_SYMBOL(qcom_scm_iommu_secure_unmap);
/**
* qcom_scm_assign_mem() - Make a secure call to reassign memory ownership
* @mem_addr: mem region whose ownership need to be reassigned

View file

@ -55,6 +55,8 @@ extern void __qcom_scm_mmu_sync(struct device *dev, bool sync);
#define QCOM_SCM_MP_RESTORE_SEC_CFG 0x02
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE 0x03
#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT 0x04
#define QCOM_SCM_MP_IOMMU_SECURE_MAP2_FLAT 0x12
#define QCOM_SCM_MP_IOMMU_SECURE_UNMAP2_FLAT 0x13
#define QCOM_SCM_MP_ASSIGN 0x16
extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
u32 spare);
@ -62,10 +64,19 @@ extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
size_t *size);
extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr,
u32 size, u32 spare);
extern int __qcom_scm_iommu_secure_map(struct device *dev,
phys_addr_t sg_list_addr, size_t num_sg,
size_t sg_block_size, u64 sec_id, int cbndx,
unsigned long iova, size_t total_len);
extern int __qcom_scm_iommu_secure_unmap(struct device *dev, u64 sec_id,
int cbndx, unsigned long iova,
size_t total_len);
extern int __qcom_scm_assign_mem(struct device *dev,
phys_addr_t mem_region, size_t mem_sz,
phys_addr_t src, size_t src_sz,
phys_addr_t dest, size_t dest_sz);
#define QCOM_SCM_IOMMU_TLBINVAL_FLAG 0x00000001
#define QCOM_SCM_SVC_HDCP 0x11
#define QCOM_SCM_HDCP_INVOKE 0x01

View file

@ -49,7 +49,7 @@
#include <linux/amba/bus.h>
#include <linux/fsl/mc.h>
#include <soc/qcom/scm.h>
#include <linux/qcom_scm.h>
#include "arm-smmu.h"
#define CREATE_TRACE_POINTS
@ -868,7 +868,7 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
int sync, int status)
{
unsigned int spin_cnt, delay;
u32 sync_inv_ack, tbu_pwr_status, sync_inv_progress;
u32 sync_inv_ack, tbu_pwr_status = -EINVAL, sync_inv_progress = -EINVAL;
u32 reg;
arm_smmu_writel(smmu, page, sync, QCOM_DUMMY_VAL);
@ -885,10 +885,11 @@ static int __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
sync_inv_ack = arm_smmu_readl(smmu,
ARM_SMMU_IMPL_DEF0,
ARM_SMMU_STATS_SYNC_INV_TBU_ACK);
tbu_pwr_status = scm_io_read((unsigned long)(smmu->phys_addr +
ARM_SMMU_TBU_PWR_STATUS));
sync_inv_progress = scm_io_read((unsigned long)(smmu->phys_addr +
ARM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR));
qcom_scm_io_readl((unsigned long)(smmu->phys_addr +
ARM_SMMU_TBU_PWR_STATUS), &tbu_pwr_status);
qcom_scm_io_readl((unsigned long)(smmu->phys_addr +
ARM_SMMU_MMU2QSS_AND_SAFE_WAIT_CNTR),
&sync_inv_progress);
trace_tlbsync_timeout(smmu->dev, 0);
dev_err_ratelimited(smmu->dev,
"TLB sync timed out -- SMMU may be deadlocked ack 0x%x pwr 0x%x sync and invalidation progress 0x%x\n",

View file

@ -53,6 +53,11 @@ extern void qcom_scm_mmu_sync(bool sync);
extern int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare);
extern int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size);
extern int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare);
extern int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr, size_t num_sg,
size_t sg_block_size, u64 sec_id, int cbndx,
unsigned long iova, size_t total_len);
extern int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx,
unsigned long iova, size_t total_len);
extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
unsigned int *src,
const struct qcom_scm_vmperm *newvm,
@ -95,6 +100,11 @@ static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
{ return -ENODEV; }
static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
{ return -ENODEV; }
static inline int qcom_scm_iommu_secure_map(phys_addr_t sg_list_addr,
size_t num_sg, size_t sg_block_size, u64 sec_id, int cbndx,
unsigned long iova, size_t total_len) { return -ENODEV; }
static inline int qcom_scm_iommu_secure_unmap(u64 sec_id, int cbndx,
unsigned long iova, size_t total_len) { return -ENODEV; }
static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
unsigned int *src,
const struct qcom_scm_vmperm *newvm,