Commit ad540a13 authored by yangxiangkai's avatar yangxiangkai
Browse files

virtcca feature: fix msi iova map

virtcca inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IAQON6



--------------------------------

VirtCCA Coda Feature:
Fix msi iova map

Signed-off-by: default avatarXiangkai Yang <yangxiangkai@huawei.com>
Signed-off-by: default avatarJunbin Li <lijunbin4@huawei.com>
---
parent 4038e2b6
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -760,6 +760,7 @@ CONFIG_KVM_HISI_VIRT=y
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_HISI_VIRTCCA_HOST=y
CONFIG_HISI_VIRTCCA_CODA=y
# CONFIG_NVHE_EL2_DEBUG is not set
CONFIG_KVM_ARM_MULTI_LPI_TRANSLATE_CACHE=y
CONFIG_ARCH_VCPU_STAT=y
+0 −1
Original line number Diff line number Diff line
@@ -83,7 +83,6 @@ struct tmi_smmu_cfg_params {
#define TMI_SMMU_CMD_QUEUE  1
#define TMI_SMMU_EVT_QUEUE  2
struct tmi_smmu_queue_params {
	uint64_t ns_src;     /* non-secure queue source address */
	uint64_t smmu_base_addr;       /* smmu base address */
	uint64_t size;       /* queue size */
	uint64_t smmu_id;    /* smmu id */
+13 −8
Original line number Diff line number Diff line
@@ -10,17 +10,20 @@
/*
 * There is a conflict with the internal iova of CVM,
 * so it is necessary to offset the msi iova.
 * According to qemu file(hw/arm/virt.c), 0x0a001000 - 0x0b000000
 * iova is not being used, so it is used as the iova range for msi
 * mapping.
 */
#define CVM_MSI_ORIG_IOVA	0x8000000
#define CVM_MSI_IOVA_OFFSET (-0x1000000)
#define CVM_MSI_MIN_IOVA	0x0a001000
#define CVM_MSI_MAX_IOVA	0x0b000000
#define CVM_MSI_IOVA_OFFSET	0x1000

#define CVM_RW_8_BIT	0x8
#define CVM_RW_16_BIT	0x10
#define CVM_RW_32_BIT	0x20
#define CVM_RW_64_BIT	0x40

#define BUS_NUM_SHIFT	0x8

enum virtcca_cvm_state {
	CVM_STATE_NONE = 1,
	CVM_STATE_NEW,
@@ -102,11 +105,8 @@ void kvm_free_rd(struct kvm *kvm);
int cvm_psci_complete(struct kvm_vcpu *calling, struct kvm_vcpu *target);

void kvm_cvm_unmap_destroy_range(struct kvm *kvm);

int kvm_cvm_map_range(struct kvm *kvm);
int cvm_arm_smmu_domain_set_kvm(void *group);
int kvm_cvm_map_unmap_ipa_range(struct kvm *kvm, phys_addr_t ipa_base, phys_addr_t pa,
	unsigned long map_size, uint32_t is_map);
int virtcca_cvm_arm_smmu_domain_set_kvm(void *group);
int cvm_map_unmap_ipa_range(struct kvm *kvm, phys_addr_t ipa_base, phys_addr_t pa,
	unsigned long map_size, uint32_t is_map);
int kvm_cvm_map_ipa_mmio(struct kvm *kvm, phys_addr_t ipa_base,
@@ -128,6 +128,11 @@ bool is_virtcca_iova_need_vfio_dma(struct kvm *kvm, uint64_t iova);
	((CVM_PAGE_SHIFT - 3) * (4 - (l)) + 3)
#define CVM_L2_BLOCK_SIZE	BIT(CVM_TTT_LEVEL_SHIFT(2))

#define TMM_GRANULE_SIZE2		12
#define TMM_TTT_WIDTH			19
#define TMM_GRANULE_SIZE		(1UL << TMM_GRANULE_SIZE2)
#define tmm_granule_size(level)	(TMM_GRANULE_SIZE << ((3 - level)) * TMM_TTT_WIDTH)

static inline unsigned long cvm_ttt_level_mapsize(int level)
{
	if (WARN_ON(level > CVM_TTT_BLOCK_LEVEL))
+41 −9
Original line number Diff line number Diff line
@@ -11,11 +11,26 @@
#include "../../../drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h"
#include "../../../drivers/iommu/arm/arm-smmu-v3/arm-s-smmu-v3.h"

#ifdef CONFIG_HISI_VIRTCCA_HOST
#ifdef CONFIG_HISI_VIRTCCA_CODA

#define MAX_CC_DEV_NUM_ORDER    8
#define MASK_DEV_FUNCTION       0xfff8
#define MASK_DEV_BUS            0xff

#define DEV_BUS_NUM             0x8
#define DEV_FUNCTION_NUM        0x3

#define STE_ENTRY_SIZE          0x40

#define SMMU_DOMAIN_IS_SAME     0x2

int virtcca_attach_secure_dev(struct iommu_domain *domain, struct iommu_group *group);
int virtcca_smmu_secure_dev_operator(struct iommu_domain *domain, struct device *dev);

struct iommu_domain *virtcca_iommu_group_get_domain(struct iommu_group *iommu_group);
u64 virtcca_get_iommu_device_msi_addr(struct iommu_group *iommu_group);
int virtcca_iommu_group_set_dev_msi_addr(struct iommu_group *iommu_group, unsigned long *iova);
int virtcca_map_msi_address(struct kvm *kvm, struct arm_smmu_domain *smmu_domain, phys_addr_t pa,
	unsigned long map_size);

int virtcca_iommu_map(struct iommu_domain *domain, unsigned long iova,
	phys_addr_t paddr, size_t size, int prot);
size_t virtcca_iommu_unmap(struct iommu_domain *domain,
@@ -28,12 +43,12 @@ size_t virtcca_unmap_pages(void *ops, unsigned long iova,

void virtcca_pci_read_msi_msg(struct pci_dev *dev, struct msi_msg *msg,
	void __iomem *base);
int virtcca_pci_write_msg_msi(struct msi_desc *desc, struct msi_msg *msg);
bool virtcca_pci_write_msg_msi(struct msi_desc *desc, struct msi_msg *msg);
void virtcca_msix_prepare_msi_desc(struct pci_dev *dev,
	struct msi_desc *desc, void __iomem *addr);
int virtcca_pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl);
int virtcca_pci_msix_mask(struct msi_desc *desc);
int msix_mask_all_cc(struct pci_dev *dev, void __iomem *base, int tsize, u64 dev_num);
bool virtcca_pci_msix_write_vector_ctrl(struct msi_desc *desc, u32 ctrl);
bool virtcca_pci_msix_mask(struct msi_desc *desc);
int virtcca_msix_mask_all_cc(struct pci_dev *dev, void __iomem *base, int tsize, u64 dev_num);

int virtcca_pci_generic_config_read(void __iomem *addr, unsigned char bus_num,
	unsigned int devfn, int size, u32 *val);
@@ -47,7 +62,7 @@ u64 virtcca_pci_io_read(struct vfio_pci_core_device *vdev,
	u64 size, void __iomem *io);

bool virtcca_iommu_domain_get_kvm(struct iommu_domain *domain, struct kvm **kvm);
bool virtcca_check_kvm_is_cvm(void *iommu, struct kvm **kvm);
bool virtcca_check_is_cvm_or_not(void *iommu, struct kvm **kvm);
int virtcca_vfio_iommu_map(void *iommu, dma_addr_t iova,
	unsigned long pfn, long npage, int prot);
int cvm_vfio_add_kvm_to_smmu_domain(struct file *filp, void *kv);
@@ -56,6 +71,23 @@ void kvm_get_arm_smmu_domain(struct kvm *kvm, struct list_head *smmu_domain_grou
struct arm_lpae_io_pgtable *virtcca_io_pgtable_get_data(void *ops);
struct io_pgtable_cfg *virtcca_io_pgtable_get_cfg(struct arm_lpae_io_pgtable *data);
struct iommu_group *cvm_vfio_file_iommu_group(struct file *file);
struct kvm *virtcca_smmu_domain_get_kvm(struct arm_lpae_io_pgtable *data);
void *virtcca_io_pgtable_get_smmu_domain(struct arm_lpae_io_pgtable *data);

struct iommu_group *virtcca_vfio_file_iommu_group(struct file *file);

bool is_cc_vmid(u32 vmid);
/* Has the root bus device number switched to secure */
bool is_cc_dev(u32 sid);

u64 get_g_cc_dev_msi_addr(u32 sid);

void set_g_cc_dev_msi_addr(u32 sid, u64 msi_addr);

void g_cc_dev_table_init(void);

u32 virtcca_tmi_dev_attach(struct arm_smmu_domain *arm_smmu_domain, struct kvm *kvm);

struct iommu_dma_msi_page *virtcca_iommu_dma_get_msi_page(struct device *dev,
	phys_addr_t msi_addr, struct iommu_domain *domain);
#endif
#endif
+1 −1
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/
obj-$(CONFIG_UNWIND_PATCH_PAC_INTO_SCS)	+= patch-scs.o
obj-$(CONFIG_IPI_AS_NMI)		+= ipi_nmi.o
obj-$(CONFIG_HISI_VIRTCCA_GUEST)	+= virtcca_cvm_guest.o virtcca_cvm_tsi.o
obj-$(CONFIG_HISI_VIRTCCA_HOST)		+= virtcca_cvm_host.o virtcca_coda.o
obj-$(CONFIG_HISI_VIRTCCA_HOST)		+= virtcca_cvm_host.o
CFLAGS_patch-scs.o			+= -mbranch-protection=none

# Force dependency (vdso*-wrap.S includes vdso.so through incbin)
Loading