misc: mods: add new ioctls

Add ioctls to read device properties and map proximity id to NUMA node.

Bug 3538850

Change-Id: I65b6decbdfbe12de7d1f1eb3edbb71b9fd56fb8a
Signed-off-by: Chris Dragan <kdragan@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2786128
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Chris Dragan
2022-10-03 08:42:09 -07:00
committed by Laxman Dewangan
parent 47a9a4cd68
commit e01a6e01a0
6 changed files with 143 additions and 10 deletions

View File

@@ -114,8 +114,8 @@ static int acpi_dev_check_one(struct acpi_device *adev, void *data)
#if KERNEL_VERSION(6, 0, 0) > MODS_KERNEL_VERSION #if KERNEL_VERSION(6, 0, 0) > MODS_KERNEL_VERSION
static int acpi_dev_each_child_node(struct acpi_device *adev, static int acpi_dev_each_child_node(struct acpi_device *adev,
int (*fptr)(struct acpi_device *, void *), int (*fptr)(struct acpi_device *, void *),
void *data) void *data)
{ {
struct list_head *node = NULL; struct list_head *node = NULL;
struct list_head *next = NULL; struct list_head *next = NULL;
@@ -719,3 +719,12 @@ int esc_mods_get_acpi_dev_children(struct mods_client *client,
LOG_EXT(); LOG_EXT();
return err; return err;
} }
#ifdef MODS_HAS_PXM_TO_NODE
int esc_mods_proximity_to_numa_node(struct mods_client *client,
struct MODS_PROXIMITY_TO_NUMA_NODE *p)
{
p->numa_node = acpi_map_pxm_to_node(p->proximity);
return OK;
}
#endif

View File

@@ -73,6 +73,10 @@
# define MODS_HAS_CONSOLE_BINDING 1 # define MODS_HAS_CONSOLE_BINDING 1
#endif #endif
#if KERNEL_VERSION(3, 19, 0) <= MODS_KERNEL_VERSION
# define MODS_HAS_DEV_PROPS 1
#endif
#if defined(CONFIG_PPC64) && KERNEL_VERSION(4, 5, 0) <= MODS_KERNEL_VERSION #if defined(CONFIG_PPC64) && KERNEL_VERSION(4, 5, 0) <= MODS_KERNEL_VERSION
# define MODS_HAS_PNV_PCI_GET_NPU_DEV 1 # define MODS_HAS_PNV_PCI_GET_NPU_DEV 1
#endif #endif
@@ -100,6 +104,10 @@
# define MODS_PCIE_FLR_HAS_ERR # define MODS_PCIE_FLR_HAS_ERR
#endif #endif
#if defined(CONFIG_ACPI_NUMA) && KERNEL_VERSION(5, 1, 0) <= MODS_KERNEL_VERSION
# define MODS_HAS_PXM_TO_NODE 1
#endif
#if KERNEL_VERSION(5, 17, 0) <= MODS_KERNEL_VERSION #if KERNEL_VERSION(5, 17, 0) <= MODS_KERNEL_VERSION
# define MODS_HAS_ACPI_FETCH 1 # define MODS_HAS_ACPI_FETCH 1
#endif #endif

View File

@@ -502,6 +502,10 @@ int esc_mods_acpi_get_ddc_2(struct mods_client *client,
struct MODS_ACPI_GET_DDC_2 *p); struct MODS_ACPI_GET_DDC_2 *p);
int esc_mods_get_acpi_dev_children(struct mods_client *client, int esc_mods_get_acpi_dev_children(struct mods_client *client,
struct MODS_GET_ACPI_DEV_CHILDREN *p); struct MODS_GET_ACPI_DEV_CHILDREN *p);
#ifdef MODS_HAS_PXM_TO_NODE
int esc_mods_proximity_to_numa_node(struct mods_client *client,
struct MODS_PROXIMITY_TO_NUMA_NODE *p);
#endif
#endif #endif
/* pci */ /* pci */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
@@ -550,6 +554,10 @@ int esc_mods_pci_set_dma_mask(struct mods_client *client,
struct MODS_PCI_DMA_MASK *dma_mask); struct MODS_PCI_DMA_MASK *dma_mask);
int esc_mods_pci_reset_function(struct mods_client *client, int esc_mods_pci_reset_function(struct mods_client *client,
struct mods_pci_dev_2 *pcidev); struct mods_pci_dev_2 *pcidev);
#ifdef MODS_HAS_DEV_PROPS
int esc_mods_read_dev_property(struct mods_client *client,
struct MODS_READ_DEV_PROPERTY *p);
#endif
#endif #endif
/* irq */ /* irq */
#if defined(MODS_HAS_TEGRA) && defined(CONFIG_OF) && defined(CONFIG_OF_IRQ) #if defined(MODS_HAS_TEGRA) && defined(CONFIG_OF) && defined(CONFIG_OF_IRQ)
@@ -635,8 +643,8 @@ int mods_init_dma(void);
void mods_exit_dma(void); void mods_exit_dma(void);
int esc_mods_dma_request_channel(struct mods_client *client, int esc_mods_dma_request_channel(struct mods_client *client,
struct MODS_DMA_HANDLE *p); struct MODS_DMA_HANDLE *p);
int esc_mods_dma_request_channel_2(struct mods_client *client, int esc_mods_dma_request_channel_2(struct mods_client *client,
struct MODS_DMA_HANDLE_2 *p_handle_2); struct MODS_DMA_HANDLE_2 *p_handle_2);
int esc_mods_dma_release_channel(struct mods_client *client, int esc_mods_dma_release_channel(struct mods_client *client,
struct MODS_DMA_HANDLE *p); struct MODS_DMA_HANDLE *p);
int esc_mods_dma_set_config(struct mods_client *client, int esc_mods_dma_set_config(struct mods_client *client,

View File

@@ -2029,6 +2029,14 @@ static long mods_krnl_ioctl(struct file *fp,
esc_mods_pci_reset_function, esc_mods_pci_reset_function,
mods_pci_dev_2); mods_pci_dev_2);
break; break;
#ifdef MODS_HAS_DEV_PROPS
case MODS_ESC_READ_DEV_PROPERTY:
MODS_IOCTL(MODS_ESC_READ_DEV_PROPERTY,
esc_mods_read_dev_property,
MODS_READ_DEV_PROPERTY);
break;
#endif
#endif #endif
case MODS_ESC_ALLOC_PAGES: case MODS_ESC_ALLOC_PAGES:
@@ -2257,8 +2265,17 @@ static long mods_krnl_ioctl(struct file *fp,
case MODS_ESC_GET_ACPI_DEV_CHILDREN: case MODS_ESC_GET_ACPI_DEV_CHILDREN:
MODS_IOCTL(MODS_ESC_GET_ACPI_DEV_CHILDREN, MODS_IOCTL(MODS_ESC_GET_ACPI_DEV_CHILDREN,
esc_mods_get_acpi_dev_children, MODS_GET_ACPI_DEV_CHILDREN); esc_mods_get_acpi_dev_children,
MODS_GET_ACPI_DEV_CHILDREN);
break; break;
#ifdef MODS_HAS_PXM_TO_NODE
case MODS_ESC_PROXIMITY_TO_NUMA_NODE:
MODS_IOCTL(MODS_ESC_PROXIMITY_TO_NUMA_NODE,
esc_mods_proximity_to_numa_node,
MODS_PROXIMITY_TO_NUMA_NODE);
break;
#endif
#else #else
case MODS_ESC_EVAL_ACPI_METHOD: case MODS_ESC_EVAL_ACPI_METHOD:
/* fallthrough */ /* fallthrough */
@@ -2437,7 +2454,7 @@ static long mods_krnl_ioctl(struct file *fp,
MODS_DMA_TX_DESC); MODS_DMA_TX_DESC);
break; break;
case MODS_ESC_DMA_TX_WAIT: case MODS_ESC_DMA_TX_WAIT:
MODS_IOCTL(MODS_ESC_DMA_TX_WAIT, MODS_IOCTL(MODS_MODS_ESC_DMA_TX_WAIT,
esc_mods_dma_wait, esc_mods_dma_wait,
MODS_DMA_WAIT_DESC); MODS_DMA_WAIT_DESC);
break; break;

View File

@@ -21,11 +21,14 @@
#include "mods_internal.h" #include "mods_internal.h"
#include <linux/device.h> #include <linux/device.h>
#if defined(MODS_HAS_DMA_OPS)
#include <linux/dma-mapping.h>
#endif
#include <linux/io.h> #include <linux/io.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/pci.h> #include <linux/pci.h>
#if defined(MODS_HAS_DMA_OPS) #if KERNEL_VERSION(3, 19, 0) <= MODS_KERNEL_VERSION
#include <linux/dma-mapping.h> #include <linux/property.h>
#endif #endif
int mods_is_pci_dev(struct pci_dev *dev, int mods_is_pci_dev(struct pci_dev *dev,
@@ -1006,3 +1009,57 @@ error:
return -EINVAL; return -EINVAL;
#endif #endif
} }
#ifdef MODS_HAS_DEV_PROPS
int esc_mods_read_dev_property(struct mods_client *client,
struct MODS_READ_DEV_PROPERTY *p)
{
struct pci_dev *dev = NULL;
int err = -EINVAL;
LOG_ENT();
if (unlikely(p->type != MODS_PROP_TYPE_U64)) {
cl_error("invalid property type %u\n", p->type);
goto error;
}
if (unlikely(sizeof(64) * p->array_size > sizeof(p->output))) {
cl_error("requested size %zu exceeds output array size %zu\n",
sizeof(u64) * p->array_size,
sizeof(p->output));
goto error;
}
if (unlikely(p->array_size == 0)) {
cl_error("invalid output array size 0\n");
goto error;
}
if (!memchr(p->prop_name, 0, sizeof(p->prop_name))) {
cl_error("invalid property name, misses terminating NUL\n");
goto error;
}
err = mods_find_pci_dev(client, &p->pci_device, &dev);
if (unlikely(err)) {
if (err == -ENODEV)
cl_error("dev %04x:%02x:%02x.%x not found\n",
p->pci_device.domain,
p->pci_device.bus,
p->pci_device.device,
p->pci_device.function);
goto error;
}
err = device_property_read_u64_array(&dev->dev, p->prop_name,
(u64 *)p->output, p->array_size);
if (unlikely(err))
cl_error("failed to read property %s\n", p->prop_name);
error:
pci_dev_put(dev);
LOG_EXT();
return err;
}
#endif

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* /*
* mods.h - This file is part of NVIDIA MODS kernel driver. * This file is part of NVIDIA MODS kernel driver.
* *
* Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved.
* *
@@ -1639,7 +1639,6 @@ struct MODS_DMA_HANDLE_2 {
char ctrl_dir[MODS_DMA_HANDLE_CTRL_DIR_LEN]; char ctrl_dir[MODS_DMA_HANDLE_CTRL_DIR_LEN];
}; };
enum MODS_DMA_TRANSFER_DIRECTION { enum MODS_DMA_TRANSFER_DIRECTION {
MODS_DMA_MEM_TO_MEM, MODS_DMA_MEM_TO_MEM,
MODS_DMA_MEM_TO_DEV, MODS_DMA_MEM_TO_DEV,
@@ -1861,6 +1860,39 @@ struct MODS_TEGRA_OIST_STATUS {
#define MODS_IOMMU_MAP_CONTIGUOUS 1 #define MODS_IOMMU_MAP_CONTIGUOUS 1
#define MODS_MAX_PROP_NAME_LEN 64
#define MODS_MAX_PROP_SIZE 8192
#define MODS_PROP_TYPE_U64 8
/* Used by MODS_ESC_READ_DEV_PROPERTY
*
* Reads a device property from firmware.
*/
struct MODS_READ_DEV_PROPERTY {
/* IN */
struct mods_pci_dev_2 pci_device;
char prop_name[MODS_MAX_PROP_NAME_LEN];
__u32 array_size;
__u8 type;
__u8 dummy_align[3];
/* OUT */
__u8 output[MODS_MAX_PROP_SIZE];
};
/* Used by MODS_ESC_PROXIMITY_TO_NUMA_NODE
*
* Converts proximity id to NUMA node id.
*/
struct MODS_PROXIMITY_TO_NUMA_NODE {
/* IN */
__s32 proximity;
/* OUT */
__s32 numa_node;
};
#pragma pack(pop) #pragma pack(pop)
#define MODS_IOC_MAGIC 'x' #define MODS_IOC_MAGIC 'x'
@@ -2063,5 +2095,7 @@ struct MODS_TEGRA_OIST_STATUS {
#define MODS_ESC_SEND_TZ_MSG MODSIO(WR, 139, MODS_TZ_PARAMS) #define MODS_ESC_SEND_TZ_MSG MODSIO(WR, 139, MODS_TZ_PARAMS)
#define MODS_ESC_OIST_STATUS MODSIO(WR, 140, MODS_TEGRA_OIST_STATUS) #define MODS_ESC_OIST_STATUS MODSIO(WR, 140, MODS_TEGRA_OIST_STATUS)
#define MODS_ESC_INVOKE_OPTEE_TA MODSIO(WR, 141, MODS_OPTEE_PARAMS) #define MODS_ESC_INVOKE_OPTEE_TA MODSIO(WR, 141, MODS_OPTEE_PARAMS)
#define MODS_ESC_READ_DEV_PROPERTY MODSIO(WR, 142, MODS_READ_DEV_PROPERTY)
#define MODS_ESC_PROXIMITY_TO_NUMA_NODE MODSIO(WR, 143, MODS_PROXIMITY_TO_NUMA_NODE)
#endif /* _UAPI_MODS_H_ */ #endif /* _UAPI_MODS_H_ */