Unverified Commit 93aea029 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11502 Virtcca feature: modify vfio/msi/iommu driver to enable confidential device assignment

Merge Pull Request from: @bob_1211 
 
Virtcca feature: modify vfio/msi/iommu driver to enable confidential device assignment 
 
Link:https://gitee.com/openeuler/kernel/pulls/11502

 

Reviewed-by: default avatarKevin Zhu <zhukeqian1@huawei.com>
Reviewed-by: default avatarWeilong Chen <chenweilong@huawei.com>
Reviewed-by: default avatarZhang Jianhua <chris.zjh@huawei.com>
Reviewed-by: default avatarLiu Chao <liuchao173@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 9a2058ed 5063d328
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
+7 −2
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 */
@@ -247,6 +246,7 @@ struct tmi_tec_run {
#define TMI_FNUM_SMMU_WRITE             U(0x282)
#define TMI_FNUM_SMMU_READ              U(0x283)
#define TMI_FNUM_SMMU_PCIE_CORE_CHECK   U(0x284)
#define TMI_FNUM_DEV_TTT_CREATE         U(0x285)

/* TMI SMC64 PIDs handled by the SPMD */
#define TMI_TMM_VERSION_REQ             TMI_FID(SMC_64, TMI_FNUM_VERSION_REQ)
@@ -280,6 +280,7 @@ struct tmi_tec_run {
#define TMI_TMM_SMMU_WRITE              TMI_FID(SMC_64, TMI_FNUM_SMMU_WRITE)
#define TMI_TMM_SMMU_READ               TMI_FID(SMC_64, TMI_FNUM_SMMU_READ)
#define TMI_TMM_SMMU_PCIE_CORE_CHECK    TMI_FID(SMC_64, TMI_FNUM_SMMU_PCIE_CORE_CHECK)
#define TMI_TMM_DEV_TTT_CREATE          TMI_FID(SMC_64, TMI_FNUM_DEV_TTT_CREATE)

#define TMI_ABI_VERSION_GET_MAJOR(_version) ((_version) >> 16)
#define TMI_ABI_VERSION_GET_MINOR(_version) ((_version) & 0xFFFF)
@@ -381,6 +382,7 @@ u64 tmi_ttt_map_range(u64 rd, u64 map_addr, u64 size, u64 cur_node, u64 target_n
u64 tmi_ttt_unmap_range(u64 rd, u64 map_addr, u64 size, u64 node_id);
u64 tmi_mem_info_show(u64 mem_info_addr);

u64 tmi_dev_ttt_create(u64 numa_set, u64 rd, u64 map_addr, u64 level);
u64 tmi_smmu_queue_create(u64 params_ptr);
u64 tmi_smmu_queue_write(uint64_t cmd0, uint64_t cmd1, u64 smmu_id);
u64 tmi_smmu_ste_create(u64 params_ptr);
@@ -396,6 +398,7 @@ u64 tmi_smmu_pcie_core_check(u64 smmu_base);
u64 tmi_smmu_write(u64 smmu_base, u64 reg_offset, u64 val, u64 bits);
u64 tmi_smmu_read(u64 smmu_base, u64 reg_offset, u64 bits);

u64 mmio_va_to_pa(void *addr);
void kvm_cvm_vcpu_put(struct kvm_vcpu *vcpu);
int kvm_load_user_data(struct kvm *kvm, unsigned long arg);
unsigned long cvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu,
@@ -404,6 +407,8 @@ int kvm_cvm_vcpu_set_events(struct kvm_vcpu *vcpu,
	bool serror_pending, bool ext_dabt_pending);
int kvm_init_cvm_vm(struct kvm *kvm);
int kvm_enable_virtcca_cvm(struct kvm *kvm);

int kvm_cvm_map_ipa(struct kvm *kvm, phys_addr_t ipa, kvm_pfn_t pfn,
	unsigned long map_size, enum kvm_pgtable_prot prot, int ret);
void virtcca_cvm_set_secure_flag(void *vdev, void *info);
#endif
#endif
+22 −5
Original line number Diff line number Diff line
@@ -10,9 +10,19 @@
/*
 * 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

enum virtcca_cvm_state {
	CVM_STATE_NONE = 1,
@@ -95,14 +105,16 @@ 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,
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,
	phys_addr_t pa, unsigned long map_size);

bool is_in_virtcca_ram_range(struct kvm *kvm, uint64_t iova);
bool is_virtcca_iova_need_vfio_dma(struct kvm *kvm, uint64_t iova);

#define CVM_TTT_BLOCK_LEVEL	2
#define CVM_TTT_MAX_LEVEL	3

@@ -116,6 +128,11 @@ int kvm_cvm_map_ipa_mmio(struct kvm *kvm, phys_addr_t ipa_base,
	((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))
+91 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (C) 2024. Huawei Technologies Co., Ltd. All rights reserved.
 */
#ifndef __VIRTCCA_CODA_H
#define __VIRTCCA_CODA_H

#include <linux/iommu.h>
#include <linux/vfio_pci_core.h>

#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_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);

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,
	unsigned long iova, size_t size);
int virtcca_map_pages(void *ops, unsigned long iova,
	phys_addr_t paddr, size_t pgsize, size_t pgcount,
	int iommu_prot, size_t *mapped);
size_t virtcca_unmap_pages(void *ops, unsigned long iova,
	size_t pgsize, size_t pgcount);

void virtcca_pci_read_msi_msg(struct pci_dev *dev, struct msi_msg *msg,
	void __iomem *base);
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);
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);
int virtcca_pci_generic_config_write(void __iomem *addr, unsigned char bus_num,
	unsigned int devfn, int size, u32 val);

bool is_virtcca_pci_io_rw(struct vfio_pci_core_device *vdev);
void virtcca_pci_io_write(struct vfio_pci_core_device *vdev, u64 val,
	u64 size, void __iomem *io);
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_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);
struct kvm *virtcca_arm_smmu_get_kvm(struct arm_smmu_domain *domain);
void kvm_get_arm_smmu_domain(struct kvm *kvm, struct list_head *smmu_domain_group_list);
struct iommu_group *cvm_vfio_file_iommu_group(struct file *file);

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);

void virtcca_iommu_dma_get_msi_page(void *cookie, dma_addr_t *iova, phys_addr_t *phys);

int virtcca_msi_map(struct vfio_pci_core_device *vdev);
#endif
#endif
+9 −3
Original line number Diff line number Diff line
@@ -19,7 +19,9 @@
#include <asm/kvm_asm.h>
#include <asm/kvm_emulate.h>
#include <asm/virt.h>

#ifdef CONFIG_HISI_VIRTCCA_CODA
#include <asm/kvm_tmi.h>
#endif
#include "trace.h"

static struct kvm_pgtable *hyp_pgtable;
@@ -871,7 +873,7 @@ int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu, unsigned long t
	u64 mmfr0, mmfr1;
	u32 phys_shift;

#ifdef CONFIG_HISI_VIRTCCA_HOST
#ifdef CONFIG_HISI_VIRTCCA_CODA
	if ((type & ~KVM_VM_TYPE_ARM_IPA_SIZE_MASK) && (!kvm_is_virtcca_cvm(kvm)))
#else
	if (type & ~KVM_VM_TYPE_ARM_IPA_SIZE_MASK)
@@ -1418,7 +1420,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,

	fault_granule = 1UL << ARM64_HW_PGTABLE_LEVEL_SHIFT(fault_level);
	write_fault = kvm_is_write_fault(vcpu);
#ifdef CONFIG_HISI_VIRTCCA_HOST
#ifdef CONFIG_HISI_VIRTCCA_CODA
	if (vcpu_is_tec(vcpu)) {
		write_fault = true;
		prot = KVM_PGTABLE_PROT_R | KVM_PGTABLE_PROT_W;
@@ -1606,6 +1608,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
					     KVM_PGTABLE_WALK_HANDLE_FAULT |
					     KVM_PGTABLE_WALK_SHARED);

#ifdef CONFIG_HISI_VIRTCCA_CODA
	ret = kvm_cvm_map_ipa(kvm, fault_ipa, pfn, vma_pagesize, prot, ret);
#endif

	/* Mark the page dirty only if the fault is handled successfully */
	if (writable && !ret) {
		kvm_set_pfn_dirty(pfn);
Loading