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 <spemmineti@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3301786
Tested-by: Joshua Cha <joshuac@nvidia.com>
GVS: buildbot_gerritrpt <buildbot_gerritrpt@nvidia.com>
Reviewed-by: Simon Je <sje@nvidia.com>
This commit is contained in:
Suneel Kumar Pemmineti
2024-09-17 15:10:52 +00:00
committed by Jon Hunter
parent b1af9a0347
commit 38d739c860
4 changed files with 124 additions and 28 deletions

View File

@@ -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 <linux/cred.h>
#include <linux/of.h>
#include <linux/fs.h>
#include <linux/uidgid.h>
#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE)
#include <linux/error-injection.h>
#endif /* CONFIG_FUNCTION_ERROR_INJECTION && CONFIG_BPF_KPROBE_OVERRIDE */
#ifdef CONFIG_TEGRA_VIRTUALIZATION
#include <soc/tegra/virt/syscalls.h>
@@ -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;

View File

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

View File

@@ -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 <nvidia/conftest.h>
@@ -17,6 +17,10 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <soc/tegra/fuse.h>
#include <linux/uidgid.h>
#if defined(CONFIG_FUNCTION_ERROR_INJECTION) && defined(CONFIG_BPF_KPROBE_OVERRIDE)
#include <linux/error-injection.h>
#endif /* CONFIG_FUNCTION_ERROR_INJECTION && CONFIG_BPF_KPROBE_OVERRIDE */
#include <uapi/linux/tegra-ivc-dev.h>
#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,

View File

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