Add support for vdev_communicate with RMM. Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@xxxxxxxxxx> --- arch/arm64/include/asm/rmi_cmds.h | 22 ++++++++++++++++++++++ arch/arm64/include/asm/rmi_smc.h | 2 ++ drivers/virt/coco/arm-cca-host/rmm-da.c | 21 +++++++++++++++++++-- drivers/virt/coco/arm-cca-host/rmm-da.h | 2 ++ 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/arch/arm64/include/asm/rmi_cmds.h b/arch/arm64/include/asm/rmi_cmds.h index 7d91f847069b..25197f47a0a9 100644 --- a/arch/arm64/include/asm/rmi_cmds.h +++ b/arch/arm64/include/asm/rmi_cmds.h @@ -587,4 +587,26 @@ static inline unsigned long rmi_vdev_create(unsigned long rd, return res.a0; } +static inline unsigned long rmi_vdev_communicate(unsigned long pdev_phys, + unsigned long vdev_phys, + unsigned long vdev_comm_data_phys) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_COMMUNICATE, + pdev_phys, vdev_phys, vdev_comm_data_phys, &res); + + return res.a0; +} + +static inline unsigned long rmi_vdev_get_state(unsigned long vdev_phys, unsigned long *state) +{ + struct arm_smccc_res res; + + arm_smccc_1_1_invoke(SMC_RMI_VDEV_GET_STATE, vdev_phys, &res); + + *state = res.a1; + return res.a0; +} + #endif /* __ASM_RMI_CMDS_H */ diff --git a/arch/arm64/include/asm/rmi_smc.h b/arch/arm64/include/asm/rmi_smc.h index e5238b271493..127dd0938604 100644 --- a/arch/arm64/include/asm/rmi_smc.h +++ b/arch/arm64/include/asm/rmi_smc.h @@ -53,7 +53,9 @@ #define SMC_RMI_PDEV_GET_STATE SMC_RMI_CALL(0x0178) #define SMC_RMI_PDEV_SET_PUBKEY SMC_RMI_CALL(0x017b) #define SMC_RMI_PDEV_STOP SMC_RMI_CALL(0x017c) +#define SMC_RMI_VDEV_COMMUNICATE SMC_RMI_CALL(0x0186) #define SMC_RMI_VDEV_CREATE SMC_RMI_CALL(0x0187) +#define SMC_RMI_VDEV_GET_STATE SMC_RMI_CALL(0x0189) #define RMI_ABI_MAJOR_VERSION 1 diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.c b/drivers/virt/coco/arm-cca-host/rmm-da.c index 41314db1d568..8635f361bbe8 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.c +++ b/drivers/virt/coco/arm-cca-host/rmm-da.c @@ -207,8 +207,14 @@ static int __do_dev_communicate(int type, struct pci_tsm *tsm) if (type == PDEV_COMMUNICATE) ret = rmi_pdev_communicate(virt_to_phys(dsc_pf0->rmm_pdev), virt_to_phys(comm_data->io_params)); - else - ret = RMI_ERROR_INPUT; + else { + struct cca_host_tdi *host_tdi = container_of(tsm->tdi, struct cca_host_tdi, tdi); + + ret = rmi_vdev_communicate(virt_to_phys(dsc_pf0->rmm_pdev), + virt_to_phys(host_tdi->rmm_vdev), + virt_to_phys(comm_data->io_params)); + } + if (ret != RMI_SUCCESS) { pr_err("pdev communicate error\n"); return ret; @@ -299,6 +305,12 @@ static int do_dev_communicate(int type, struct pci_tsm *tsm, int target_state) ret = rmi_pdev_get_state(virt_to_phys(dsc_pf0->rmm_pdev), &state); error_state = RMI_PDEV_ERROR; + } else { + struct cca_host_tdi *host_tdi = container_of(tsm->tdi, struct cca_host_tdi, tdi); + + ret = rmi_vdev_get_state(virt_to_phys(host_tdi->rmm_vdev), + &state); + error_state = RMI_VDEV_ERROR; } if (ret != 0) { pr_err("Get dev state error\n"); @@ -584,3 +596,8 @@ void *rme_create_vdev(struct realm *realm, struct pci_dev *pdev, err_out: return ERR_PTR(ret); } + +static int __maybe_unused do_vdev_communicate(struct pci_tsm *tsm, int target_state) +{ + return do_dev_communicate(VDEV_COMMUNICATE, tsm, target_state); +} diff --git a/drivers/virt/coco/arm-cca-host/rmm-da.h b/drivers/virt/coco/arm-cca-host/rmm-da.h index 6d612ea3b87f..37a8f4dce68e 100644 --- a/drivers/virt/coco/arm-cca-host/rmm-da.h +++ b/drivers/virt/coco/arm-cca-host/rmm-da.h @@ -51,6 +51,8 @@ struct cca_host_tdi { }; #define PDEV_COMMUNICATE 0x1 +#define VDEV_COMMUNICATE 0x2 + static inline struct cca_host_dsc_pf0 *to_cca_dsc_pf0(struct pci_dev *pdev) { struct pci_tsm *tsm = pdev->tsm; -- 2.43.0