* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _KVMDT_H_
#define _KVMDT_H_
#include "dvt.h"
* Specific MPT modules function collections.
*/
struct hw_kvmdt_ops {
int (*register_mdev)(struct device *dev, struct hw_dvt *dvt);
void (*unregister_mdev)(struct device *dev, struct hw_dvt *dvt);
int (*attach_vdavinci)(void *vdavinci, uintptr_t handle);
void (*detach_vdavinci)(void *vdavinci);
int (*inject_msix)(uintptr_t handle, u32 vector);
unsigned long (*from_virt_to_mfn)(void *addr);
int (*read_gpa)(uintptr_t handle, unsigned long gpa, void *buf,
unsigned long len);
int (*write_gpa)(uintptr_t handle, unsigned long gpa, void *buf,
unsigned long len);
unsigned long (*gfn_to_mfn)(uintptr_t handle, unsigned long gfn);
bool (*is_valid_gfn)(uintptr_t handle, unsigned long gfn);
int (*mmio_get)(void **dst, int *size, void *_vdavinci, int bar);
int (*dma_pool_init)(struct hw_vdavinci *vdavinci);
void (*dma_pool_uninit)(struct hw_vdavinci *vdavinci);
int (*dma_get_iova)(struct hw_vdavinci *vdavinci, unsigned long gfn,
unsigned long size, struct sg_table **dma_sgt);
void (*dma_put_iova)(struct sg_table *dma_sgt);
int (*dma_get_iova_batch)(struct hw_vdavinci *vdavinci, unsigned long *gfn,
unsigned long *dma_addr, unsigned long count);
};
struct kvmdt_guest_info {
struct kvm *kvm;
struct hw_vdavinci *vdavinci;
struct dentry *debugfs_cache_entries;
};
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,0))
struct hw_vfio_vdavinci {
struct vfio_device vfio_dev;
struct hw_vdavinci *vdavinci;
};
#endif
struct dvt_dma {
struct hw_vdavinci *vdavinci;
struct rb_node gfn_node;
struct rb_node dma_node;
gfn_t gfn;
dma_addr_t dma_addr;
unsigned long size;
struct sg_table *dma_sgt;
struct page_info_list *dma_page_list;
struct kref ref;
};
void kvmdt_dma_unmap_guest_page(uintptr_t handle, struct sg_table *dma_sgt);
int kvmdt_dma_map_guest_page(uintptr_t handle, unsigned long gfn,
unsigned long size, struct sg_table **dma_sgt);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6,0,0))
void dvt_cache_remove_ram(struct hw_vdavinci *vdavinci,
unsigned long start_gfn, unsigned long size);
#endif
#if ((LINUX_VERSION_CODE == KERNEL_VERSION(4,4,0)) && (!defined(DRV_UT)))
static inline bool mmget_not_zero(struct mm_struct *mm)
{
return atomic_inc_not_zero(&mm->mm_users);
}
#endif
bool get_node_cpu_by_page(struct hw_vdavinci *vdavinci,
unsigned int current_cpu,
struct page *page,
struct cpumask *cpumask);
struct hw_vdavinci *hw_vdavinci_create(struct kobject *kobj, struct mdev_device *mdev);
int hw_vdavinci_remove(struct mdev_device *mdev);
int hw_vdavinci_open(struct mdev_device *mdev);
void hw_vdavinci_release(struct mdev_device *mdev);
ssize_t hw_vdavinci_read(struct mdev_device *mdev, char __user *buf,
size_t count, loff_t *ppos);
size_t hw_vdavinci_write(struct mdev_device *mdev,
const char __user *buf,
size_t count, loff_t *ppos);
int hw_vdavinci_mmap(struct mdev_device *mdev, struct vm_area_struct *vma);
long hw_vdavinci_ioctl(struct mdev_device *mdev, unsigned int cmd,
unsigned long arg);
#endif