* 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.
*/
#include "virtmng_public_def.h"
#include "virtmnghost_ctrl.h"
#include "vmng_mem_alloc_interface.h"
#include "virtmnghost_proc_fs.h"
#define STATIC_PROCFS_FILE_FUNC_OPS(ops, open_func, write_func) \
static const ka_procfs_ops_t ops = { \
ka_fs_init_pf_owner(KA_THIS_MODULE) \
ka_fs_init_pf_open(open_func) \
ka_fs_init_pf_read(ka_fs_seq_read) \
ka_fs_init_pf_lseek(ka_fs_seq_lseek) \
ka_fs_init_pf_release(ka_fs_single_release) \
ka_fs_init_pf_write(write_func) \
}
static ka_proc_dir_entry_t *vmng_host_entry = NULL;
static struct vmngh_user_input g_host_id = {
.dev_id = 0,
.vfid = 1,
};
static struct vmngh_procfs_entry g_procfs_entry = {
.dev_id = NULL,
.vf_id = NULL,
.each_resource_info = NULL,
};
#define MSG_SIZE 3
#define KSTRTOL_BASE 10
STATIC ssize_t set_global_id(ka_file_t *filp, const char *buf, size_t count, loff_t *offp, u32 *output)
{
char *msg;
int ret = 0;
long temp;
if (count > MSG_SIZE) {
ret = -EINVAL;
vmng_err("Set_global_id count size err!\n");
goto error;
}
msg = vmng_kzalloc(MSG_SIZE, KA_GFP_KERNEL);
if (msg == NULL) {
ret = -ENOMEM;
vmng_err("Set_global_id ka_mm_kzalloc err!\n");
goto error;
}
if (ka_base_copy_from_user(msg, buf, count)) {
ret = -EFAULT;
vmng_err("Set_global_id ka_base_copy_from_user err!\n");
goto free;
}
#ifndef VIRTMNG_UT
msg[MSG_SIZE - 1] = '\0';
#endif
ret = ka_base_kstrtol(msg, KSTRTOL_BASE, &temp);
if ((ret != 0) || (temp < 0) || (temp >= KA_INT_MAX)) {
ret = -EINVAL;
vmng_err("Set_global_id ka_base_kstrtol err!\n");
goto free;
}
KA_WRITE_ONCE(*output, (u32)temp);
ret = (int)count;
free:
vmng_kfree(msg);
error:
return ret;
}
STATIC ssize_t write_dev_id(ka_file_t *filp, const char *buf, size_t count, loff_t *offp)
{
u32 dev_id = 0;
int ret = 0;
ret = set_global_id(filp, buf, count, offp, &dev_id);
if (dev_id >= ASCEND_PDEV_MAX_NUM) {
ret = -ERANGE;
} else {
g_host_id.dev_id = dev_id;
}
return ret;
}
STATIC int read_dev_id_proc_show(ka_seq_file_t *m, void *v)
{
ka_fs_seq_printf(m, "[ dev_id = %u ]\n", g_host_id.dev_id);
return 0;
}
STATIC int read_dev_id_proc_open(ka_inode_t *inode, ka_file_t *file)
{
return ka_fs_single_open(file, read_dev_id_proc_show, NULL);
}
STATIC ssize_t write_vfid(ka_file_t *filp, const char *buf, size_t count, loff_t *offp)
{
u32 vfid = 0;
int ret = 0;
ret = set_global_id(filp, buf, count, offp, &vfid);
if (vfid >= VMNG_VDEV_MAX_PER_PDEV) {
ret = -ERANGE;
} else {
g_host_id.vfid = vfid;
}
return ret;
}
STATIC int read_vfid_proc_show(ka_seq_file_t *m, void *v)
{
ka_fs_seq_printf(m, "[ vfid = %u ]\n", g_host_id.vfid);
return 0;
}
STATIC int read_vfid_proc_open(ka_inode_t *inode, ka_file_t *file)
{
return ka_fs_single_open(file, read_vfid_proc_show, NULL);
}
STATIC void vf_res_id_info_proc_show(ka_seq_file_t *m, void *v, vf_id_info_t *id)
{
ka_fs_seq_printf(m, "[id_info]:\n");
ka_fs_seq_printf(m, "\tvf_id = %u\n", id->vf_id);
ka_fs_seq_printf(m, "\tvfg_mode = %u\n", id->vfg_mode);
ka_fs_seq_printf(m, "\tvfg_id = %u\n", id->vfg_id);
ka_fs_seq_printf(m, "\tvip = %u\n", id->vip);
ka_fs_seq_printf(m, "\ttoken = %#llx\n", id->token);
ka_fs_seq_printf(m, "\ttoken_max = %#llx\n", id->token_max);
ka_fs_seq_printf(m, "\ttask_timeout = %#llx\n", id->task_timeout);
return;
}
STATIC void vf_res_ac_info_proc_show(ka_seq_file_t *m, void *v, vf_ac_info_t *accelerator)
{
ka_fs_seq_printf(m, "[accelerator]:\n");
ka_fs_seq_printf(m, "\taiv_bitmap = %#llx\n", accelerator->aiv_bitmap);
ka_fs_seq_printf(m, "\taic_bitmap = %#x\n", accelerator->aic_bitmap);
ka_fs_seq_printf(m, "\tc_core_bitmap = %#x\n", accelerator->c_core_bitmap);
ka_fs_seq_printf(m, "\tdsa_bitmap = %#x\n", accelerator->dsa_bitmap);
ka_fs_seq_printf(m, "\tffts_bitmap = %#x\n", accelerator->ffts_bitmap);
ka_fs_seq_printf(m, "\tsdma_bitmap = %#x\n", accelerator->sdma_bitmap);
ka_fs_seq_printf(m, "\tpcie_dma_bitmap = %#x\n", accelerator->pcie_dma_bitmap);
ka_fs_seq_printf(m, "\tacsq_slice_bitmap = %#x\n", accelerator->acsq_slice_bitmap);
ka_fs_seq_printf(m, "\trtsq_slice_bitmap = %#x\n", accelerator->rtsq_slice_bitmap);
ka_fs_seq_printf(m, "\tevent_slice_bitmap = %#x\n", accelerator->event_slice_bitmap);
ka_fs_seq_printf(m, "\tnotify_slice_bitmap = %#x\n", accelerator->notify_slice_bitmap);
ka_fs_seq_printf(m, "\tcdq_slice_bitmap = %#x\n", accelerator->cdq_slice_bitmap);
ka_fs_seq_printf(m, "\tcmo_slice_bitmap = %#x\n", accelerator->cmo_slice_bitmap);
return;
}
STATIC void vf_res_cpu_info_proc_show(ka_seq_file_t *m, void *v, vf_cpu_info_t *cpu)
{
ka_fs_seq_printf(m, "[cpu]:\n");
ka_fs_seq_printf(m, "\ttopic_aicpu_slot = %#x\n", cpu->topic_aicpu_slot_bitmap);
ka_fs_seq_printf(m, "\ttopic_ctrl_cpu_slot = %#x\n", cpu->topic_ctrl_cpu_slot_bitmap);
ka_fs_seq_printf(m, "\thost_ctrl_cpu = %#x\n", cpu->host_ctrl_cpu_bitmap);
ka_fs_seq_printf(m, "\tdevice_aicpu = %#x\n", cpu->device_aicpu_bitmap);
ka_fs_seq_printf(m, "\thost_aicpu = %#llx\n", cpu->host_aicpu_bitmap);
return;
}
STATIC void vf_res_dvpp_info_proc_show(ka_seq_file_t *m, void *v, vf_dvpp_info_t *dvpp)
{
ka_fs_seq_printf(m, "[dvpp]:\n");
ka_fs_seq_printf(m, "\tjpegd_bitmap = %#x\n", dvpp->jpegd_bitmap);
ka_fs_seq_printf(m, "\tjpege_bitmap = %#x\n", dvpp->jpege_bitmap);
ka_fs_seq_printf(m, "\tvpc_bitmap = %#x\n", dvpp->vpc_bitmap);
ka_fs_seq_printf(m, "\tvdec_bitmap = %#x\n", dvpp->vdec_bitmap);
ka_fs_seq_printf(m, "\tpngd_bitmap = %#x\n", dvpp->pngd_bitmap);
ka_fs_seq_printf(m, "\tvenc_bitmap = %#x\n", dvpp->venc_bitmap);
return;
}
STATIC void vf_res_info_proc_show(ka_seq_file_t *m, void *v, struct vmngh_vdev_ctrl *ctrl)
{
struct vmng_vdev_ctrl *vdev_ctrl = &ctrl->vdev_ctrl;
vmng_vf_cfg_t *vf_cfg = &vdev_ctrl->vf_cfg;
ka_fs_seq_printf(m, "\tstatus = %u\n", vdev_ctrl->status);
ka_fs_seq_printf(m, "\tdev_id = %u\n", vdev_ctrl->dev_id);
ka_fs_seq_printf(m, "\tvfid = %u\n", vdev_ctrl->vfid);
ka_fs_seq_printf(m, "\tvm_devid = %u\n", vdev_ctrl->vm_devid);
ka_fs_seq_printf(m, "\tvm_id = %u\n", vdev_ctrl->vm_id);
ka_fs_seq_printf(m, "\tdtype = %u\n", vdev_ctrl->dtype);
ka_fs_seq_printf(m, "\tcore_num = %u\n", vdev_ctrl->core_num);
ka_fs_seq_printf(m, "\ttotal_core_num = %u\n", vdev_ctrl->total_core_num);
ka_fs_seq_printf(m, "\tddr_size = %#llx\n", vdev_ctrl->ddr_size);
ka_fs_seq_printf(m, "\thbm_size = %#llx\n", vdev_ctrl->hbm_size);
ka_fs_seq_printf(m, "\tbar0_size = %#llx\n", vdev_ctrl->bar0_size);
ka_fs_seq_printf(m, "\tbar2_size = %#llx\n", vdev_ctrl->bar2_size);
ka_fs_seq_printf(m, "\tbar4_size = %#llx\n", vdev_ctrl->bar4_size);
ka_fs_seq_printf(m, "\tcapbility = %u\n", vf_cfg->capbility);
ka_fs_seq_printf(m, "\tnuma_id.bitmap = %#lx\n", ctrl->memory.numa_id.bitmap);
vf_res_id_info_proc_show(m, v, &vf_cfg->id);
vf_res_ac_info_proc_show(m, v, &vf_cfg->accelerator);
vf_res_cpu_info_proc_show(m, v, &vf_cfg->cpu);
vf_res_dvpp_info_proc_show(m, v, &vf_cfg->dvpp);
return;
}
STATIC int each_resource_info_proc_show(ka_seq_file_t *m, void *v)
{
struct vmngh_vdev_ctrl *ctrl = NULL;
u32 dev_id = g_host_id.dev_id;
u32 vfid = g_host_id.vfid;
ctrl = vmngh_get_ctrl(dev_id, vfid);
if (ctrl == NULL) {
ka_fs_seq_printf(m, "Vmngh get ctrl failed, please input valid id.(dev_id = %d; vfid = %d)\n", dev_id, vfid);
return 0;
}
ka_fs_seq_printf(m, "\n----------- dev_id = %d / vfid = %d -----------\n", dev_id, vfid);
vf_res_info_proc_show(m, v, ctrl);
return 0;
}
STATIC int each_resource_info_proc_open(ka_inode_t *inode, ka_file_t *file)
{
return ka_fs_single_open(file, each_resource_info_proc_show, NULL);
}
STATIC_PROCFS_FILE_FUNC_OPS(vmngh_dev_id_ops, read_dev_id_proc_open, write_dev_id);
STATIC_PROCFS_FILE_FUNC_OPS(vmngh_vfid_ops, read_vfid_proc_open, write_vfid);
STATIC_PROCFS_FILE_FUNC_OPS(vmngh_each_resource_ops, each_resource_info_proc_open, NULL);
STATIC int vmngh_dev_id_proc_fs(void)
{
g_procfs_entry.dev_id = ka_fs_proc_create_data("dev_id", KA_S_IRUSR | KA_S_IWUSR, vmng_host_entry, &vmngh_dev_id_ops, NULL);
if (g_procfs_entry.dev_id == NULL) {
vmng_err("Create dev_id_entry dir failed.\n");
return VMNG_ERR;
}
return VMNG_OK;
}
STATIC int vmngh_vf_id_proc_fs(void)
{
g_procfs_entry.vf_id = ka_fs_proc_create_data("vf_id", KA_S_IRUSR | KA_S_IWUSR, vmng_host_entry, &vmngh_vfid_ops, NULL);
if (g_procfs_entry.vf_id == NULL) {
vmng_err("Create vf_id_entry dir failed.\n");
return VMNG_ERR;
}
return VMNG_OK;
}
STATIC int vmngh_each_resource_info_proc_fs(void)
{
g_procfs_entry.each_resource_info = ka_fs_proc_create_data("each_resource_info", KA_S_IRUSR,
vmng_host_entry, &vmngh_each_resource_ops, NULL);
if (g_procfs_entry.each_resource_info == NULL) {
vmng_err("Create each_resource_info_entry dir failed.\n");
return VMNG_ERR;
}
return VMNG_OK;
}
int vmngh_proc_fs_init(void)
{
vmng_host_entry = ka_fs_proc_mkdir("vmng_host", NULL);
if (vmng_host_entry == NULL) {
vmng_err("Create vmng_host entry dir failed\n");
return VMNG_ERR;
}
if ((vmngh_dev_id_proc_fs() != 0) ||
(vmngh_vf_id_proc_fs() != 0) ||
(vmngh_each_resource_info_proc_fs() != 0)) {
(void)ka_fs_remove_proc_subtree("vmng_host", NULL);
vmng_err("Vmng_host proc fs init failed.\n");
return VMNG_ERR;
}
return VMNG_OK;
}
void vmngh_proc_fs_uninit(void)
{
(void)ka_fs_remove_proc_subtree("vmng_host", NULL);
return;
}