From 38d739c860fb63f6cf52c9e4890d70a07789715a Mon Sep 17 00:00:00 2001 From: Suneel Kumar Pemmineti Date: Tue, 17 Sep 2024 15:10:52 +0000 Subject: [PATCH] nvsciipc: Add UID member to Config structure - Added UID member to nvsciipc_config_entry data structure. this is needed for implementing test_nvsciipc_cfgblob in linux. - removed static from ioctl function to attach eBPF program - add error-injection.h and ALLOW_ERROR_INJECTION macro to ioctl to use bpf_override_return() JIRA NVIPC-2817 Change-Id: Ic27156e321368041f41fbabff9e6375140fe1d0e Signed-off-by: Suneel Kumar Pemmineti Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3301786 Tested-by: Joshua Cha GVS: buildbot_gerritrpt Reviewed-by: Simon Je --- drivers/misc/nvsciipc/nvsciipc.c | 88 +++++++++++++++++++++++------ drivers/misc/nvsciipc/nvsciipc.h | 8 +-- drivers/virt/tegra/ivc-cdev.c | 14 ++++- include/uapi/linux/nvsciipc_ioctl.h | 42 ++++++++++++-- 4 files changed, 124 insertions(+), 28 deletions(-) diff --git a/drivers/misc/nvsciipc/nvsciipc.c b/drivers/misc/nvsciipc/nvsciipc.c index 11e654e6..92a19565 100644 --- a/drivers/misc/nvsciipc/nvsciipc.c +++ b/drivers/misc/nvsciipc/nvsciipc.c @@ -1,7 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - */ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. /* * This is NvSciIpc kernel driver. At present its only use is to support @@ -24,6 +22,10 @@ #include #include #include +#include +#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE) +#include +#endif /* CONFIG_FUNCTION_ERROR_INJECTION && CONFIG_BPF_KPROBE_OVERRIDE */ #ifdef CONFIG_TEGRA_VIRTUALIZATION #include @@ -40,7 +42,6 @@ /* enable it to debug auth API via ioctl. * enable LINUX_DEBUG_KMD_API in test_nvsciipc_nvmap tool either. */ -#define DEBUG_AUTH_API 1 #define DEBUG_VALIDATE_TOKEN 0 DEFINE_MUTEX(nvsciipc_mutex); @@ -51,6 +52,9 @@ static struct nvsciipc *ctx; static int32_t s_guestid = -1; #endif /* CONFIG_TEGRA_VIRTUALIZATION */ +long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); + NvSciError NvSciIpcEndpointGetAuthToken(NvSciIpcEndpoint handle, NvSciIpcEndpointAuthToken *authToken) { @@ -228,7 +232,6 @@ static int nvsciipc_dev_release(struct inode *inode, struct file *filp) return 0; } -#if DEBUG_AUTH_API static int nvsciipc_ioctl_validate_auth_token(struct nvsciipc *ctx, unsigned int cmd, unsigned long arg) { @@ -304,7 +307,6 @@ static int nvsciipc_ioctl_map_vuid(struct nvsciipc *ctx, unsigned int cmd, exit: return ret; } -#endif /* DEBUG_AUTH_API */ static int nvsciipc_ioctl_get_db_by_idx(struct nvsciipc *ctx, unsigned int cmd, unsigned long arg) @@ -376,6 +378,47 @@ static int nvsciipc_ioctl_get_db_by_name(struct nvsciipc *ctx, unsigned int cmd, return 0; } +// TODO: remove this after migration +static int nvsciipc_ioctl_get_db_by_name_legacy(struct nvsciipc *ctx, + unsigned int cmd, unsigned long arg) +{ + struct nvsciipc_get_db_by_name_legacy get_db; + int i; + + if ((ctx->num_eps == 0) || (ctx->set_db_f != true)) { + ERR("%s[%d] need to set endpoint database first\n", __func__, + get_current()->pid); + return -EPERM; + } + + if (copy_from_user(&get_db, (void __user *)arg, _IOC_SIZE(cmd))) { + ERR("%s : copy_from_user failed\n", __func__); + return -EFAULT; + } + + /* read operation */ + for (i = 0; i < ctx->num_eps; i++) { + if (!strncmp(get_db.ep_name, ctx->db[i]->ep_name, + NVSCIIPC_MAX_EP_NAME)) { + //get_db.entry = *ctx->db[i]; + memcpy(&get_db.entry, ctx->db[i], sizeof(get_db.entry)); + get_db.idx = i; + break; + } + } + + if (i == ctx->num_eps) { + INFO("%s: no entry (%s)\n", __func__, get_db.ep_name); + return -ENOENT; + } else if (copy_to_user((void __user *)arg, &get_db, + _IOC_SIZE(cmd))) { + ERR("%s : copy_to_user failed\n", __func__); + return -EFAULT; + } + + return 0; +} + static int nvsciipc_ioctl_get_db_by_vuid(struct nvsciipc *ctx, unsigned int cmd, unsigned long arg) { @@ -469,8 +512,9 @@ static int nvsciipc_ioctl_set_db(struct nvsciipc *ctx, unsigned int cmd, return -EPERM; } #else - /* check root user */ - if (current_cred()->uid.val != 0) { + /* check root or nvsciipc user */ + if ((current_cred()->uid.val != 0) && + (current_cred()->uid.val != 2000)) { ERR("no permission to set db\n"); return -EPERM; } @@ -617,7 +661,9 @@ exit: return ret; } -static long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, +// TODO: remove macro after change delivery btw branches +#define NVSCIIPC_IOCTL_GET_DB_BY_NAME_LEGACY 0xc140c303 +long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct nvsciipc *ctx = filp->private_data; @@ -647,6 +693,10 @@ static long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, case NVSCIIPC_IOCTL_GET_DB_BY_NAME: ret = nvsciipc_ioctl_get_db_by_name(ctx, cmd, arg); break; +// TODO: remove legacy cmd after migration + case NVSCIIPC_IOCTL_GET_DB_BY_NAME_LEGACY: + ret = nvsciipc_ioctl_get_db_by_name_legacy(ctx, cmd, arg); + break; case NVSCIIPC_IOCTL_GET_DB_BY_VUID: ret = nvsciipc_ioctl_get_db_by_vuid(ctx, cmd, arg); break; @@ -656,14 +706,12 @@ static long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, case NVSCIIPC_IOCTL_GET_DB_SIZE: ret = nvsciipc_ioctl_get_dbsize(ctx, cmd, arg); break; -#if DEBUG_AUTH_API case NVSCIIPC_IOCTL_VALIDATE_AUTH_TOKEN: ret = nvsciipc_ioctl_validate_auth_token(ctx, cmd, arg); break; case NVSCIIPC_IOCTL_MAP_VUID: ret = nvsciipc_ioctl_map_vuid(ctx, cmd, arg); break; -#endif /* DEBUG_AUTH_API */ case NVSCIIPC_IOCTL_GET_VMID: #ifdef CONFIG_TEGRA_VIRTUALIZATION if (copy_to_user((void __user *) arg, &s_guestid, @@ -681,6 +729,9 @@ static long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, } exit: +#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE) + ALLOW_ERROR_INJECTION(nvsciipc_dev_ioctl, ERRNO); +#endif /* CONFIG_FUNCTION_ERROR_INJECTION && defined(CONFIG_BPF_KPROBE_OVERRIDE */ return ret; } @@ -691,7 +742,8 @@ static ssize_t nvsciipc_dbg_read(struct file *filp, char __user *buf, int i; /* check root user */ - if (current_cred()->uid.val != 0) { + if ((current_cred()->uid.val != 0) && + (current_cred()->uid.val != 2000)) { ERR("no permission to read db\n"); return -EPERM; } @@ -703,14 +755,16 @@ static ssize_t nvsciipc_dbg_read(struct file *filp, char __user *buf, } for (i = 0; i < ctx->num_eps; i++) { - INFO("EP[%03d]: ep:%s,dev:%s,be:%u,nfrm:%u,fsz:%u,id:%u,noti:%d(TRAP:1,MSI:2)\n", i, - ctx->db[i]->ep_name, + INFO("EP[%03d]: ep_name: %s, dev_name: %s, backend: %u, nframes: %u, ", + i, ctx->db[i]->ep_name, ctx->db[i]->dev_name, ctx->db[i]->backend, - ctx->db[i]->nframes, + ctx->db[i]->nframes); + INFO("frame_size: %u, id: %u, noti:%d(TRAP:1,MSI:2), uid: %d\n", ctx->db[i]->frame_size, ctx->db[i]->id, - ctx->db[i]->noti_type); + ctx->db[i]->noti_type, + ctx->db[i]->uid); } return 0; diff --git a/drivers/misc/nvsciipc/nvsciipc.h b/drivers/misc/nvsciipc/nvsciipc.h index 122b8099..1de00fcb 100644 --- a/drivers/misc/nvsciipc/nvsciipc.h +++ b/drivers/misc/nvsciipc/nvsciipc.h @@ -1,7 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2019-2023, NVIDIA CORPORATION. All rights reserved. - */ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #ifndef __NVSCIIPC_KERNEL_H__ #define __NVSCIIPC_KERNEL_H__ @@ -59,7 +57,7 @@ static void nvsciipc_cleanup(struct nvsciipc *ctx); static int nvsciipc_dev_open(struct inode *inode, struct file *filp); static int nvsciipc_dev_release(struct inode *inode, struct file *filp); -static long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, +long nvsciipc_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); static int nvsciipc_ioctl_get_vuid(struct nvsciipc *ctx, unsigned int cmd, unsigned long arg); diff --git a/drivers/virt/tegra/ivc-cdev.c b/drivers/virt/tegra/ivc-cdev.c index ae98f8a6..132188f9 100644 --- a/drivers/virt/tegra/ivc-cdev.c +++ b/drivers/virt/tegra/ivc-cdev.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * SPDX-FileCopyrightText: Copyright (c) 2022-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-FileCopyrightText: Copyright (c) 2022-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ #include @@ -17,6 +17,10 @@ #include #include #include +#include +#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE) +#include +#endif /* CONFIG_FUNCTION_ERROR_INJECTION && CONFIG_BPF_KPROBE_OVERRIDE */ #include #include "tegra_hv.h" @@ -54,6 +58,8 @@ static const struct ivc_info_page *s_infop; /* setup_ivc() set guest id */ static uint32_t s_guestid = INVALID_VMID; +long ivc_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg); static irqreturn_t ivc_dev_handler(int irq, void *data) { @@ -239,7 +245,7 @@ static int ivc_dev_mmap(struct file *filp, struct vm_area_struct *vma) /* Need this temporarily to get the change merged. Will be removed later */ #define NVIPC_IVC_IOCTL_GET_INFO_LEGACY 0xC018AA01 #define NVIPC_IVC_IOCTL_NOTIFY_REMOTE_LEGACY 0xC018AA02 -static long ivc_dev_ioctl(struct file *filp, unsigned int cmd, +long ivc_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct ivc_dev *ivcd = filp->private_data; @@ -337,8 +343,12 @@ static long ivc_dev_ioctl(struct file *filp, unsigned int cmd, } exit: +#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE) + ALLOW_ERROR_INJECTION(ivc_dev_ioctl, ERRNO); +#endif /* CONFIG_FUNCTION_ERROR_INJECTION && CONFIG_BPF_KPROBE_OVERRIDE */ return ret; } +EXPORT_SYMBOL(ivc_dev_ioctl); static const struct file_operations ivc_fops = { .owner = THIS_MODULE, diff --git a/include/uapi/linux/nvsciipc_ioctl.h b/include/uapi/linux/nvsciipc_ioctl.h index 5d1decce..06dde7c5 100644 --- a/include/uapi/linux/nvsciipc_ioctl.h +++ b/include/uapi/linux/nvsciipc_ioctl.h @@ -1,7 +1,5 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - */ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. #ifndef __NVSCIIPC_IOCTL_H__ #define __NVSCIIPC_IOCTL_H__ @@ -32,6 +30,30 @@ struct nvsciipc_config_entry { uint32_t local_port; uint32_t peer_vmid; uint32_t noti_type; + uint32_t uid; +}; + +/* TODO: remove it after migration */ +struct nvsciipc_config_entry_legacy { + /* endpoint name */ + char ep_name[NVSCIIPC_MAX_EP_NAME]; + /* node name for shm/sem */ + char dev_name[NVSCIIPC_MAX_EP_NAME]; + uint32_t backend; /* backend type */ + uint32_t nframes; /* frame count */ + uint32_t frame_size; /* frame size */ + /* ep id for inter-Proc/Thread + * queue id for inter-VM + * dev id for inter-Chip + */ + uint32_t id; + uint64_t vuid; /* VM-wide unique id */ + char rdma_dev_name[NVSCIIPC_MAX_RDMA_NAME]; + char remote_ip[NVSCIIPC_MAX_IP_NAME]; + uint32_t remote_port; + uint32_t local_port; + uint32_t peer_vmid; + uint32_t noti_type; }; struct nvsciipc_db { @@ -44,12 +66,24 @@ struct nvsciipc_get_vuid { uint64_t vuid; }; +struct nvsciipc_get_db_by_id { + uint32_t id; // IVC qid + struct nvsciipc_config_entry entry; +}; + struct nvsciipc_get_db_by_name { char ep_name[NVSCIIPC_MAX_EP_NAME]; struct nvsciipc_config_entry entry; uint32_t idx; }; +/* TODO: remove it after migration */ +struct nvsciipc_get_db_by_name_legacy { + char ep_name[NVSCIIPC_MAX_EP_NAME]; + struct nvsciipc_config_entry_legacy entry; + uint32_t idx; +}; + struct nvsciipc_get_db_by_vuid { uint64_t vuid; struct nvsciipc_config_entry entry;