From e01a6e01a04b449476b6b13b36a465589fbf926f Mon Sep 17 00:00:00 2001 From: Chris Dragan Date: Mon, 3 Oct 2022 08:42:09 -0700 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2786128 Reviewed-by: svc-mobile-coverity Reviewed-by: Sachin Nikam GVS: Gerrit_Virtual_Submit --- drivers/misc/mods/mods_acpi.c | 13 ++++++- drivers/misc/mods/mods_config.h | 8 ++++ drivers/misc/mods/mods_internal.h | 12 +++++- drivers/misc/mods/mods_krnl.c | 21 ++++++++++- drivers/misc/mods/mods_pci.c | 61 ++++++++++++++++++++++++++++++- include/uapi/misc/mods.h | 38 ++++++++++++++++++- 6 files changed, 143 insertions(+), 10 deletions(-) diff --git a/drivers/misc/mods/mods_acpi.c b/drivers/misc/mods/mods_acpi.c index 8077eab4..58c07474 100644 --- a/drivers/misc/mods/mods_acpi.c +++ b/drivers/misc/mods/mods_acpi.c @@ -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 static int acpi_dev_each_child_node(struct acpi_device *adev, - int (*fptr)(struct acpi_device *, void *), - void *data) + int (*fptr)(struct acpi_device *, void *), + void *data) { struct list_head *node = NULL; struct list_head *next = NULL; @@ -719,3 +719,12 @@ int esc_mods_get_acpi_dev_children(struct mods_client *client, LOG_EXT(); 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 diff --git a/drivers/misc/mods/mods_config.h b/drivers/misc/mods/mods_config.h index 9edf9ef6..14164f91 100644 --- a/drivers/misc/mods/mods_config.h +++ b/drivers/misc/mods/mods_config.h @@ -73,6 +73,10 @@ # define MODS_HAS_CONSOLE_BINDING 1 #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 # define MODS_HAS_PNV_PCI_GET_NPU_DEV 1 #endif @@ -100,6 +104,10 @@ # define MODS_PCIE_FLR_HAS_ERR #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 # define MODS_HAS_ACPI_FETCH 1 #endif diff --git a/drivers/misc/mods/mods_internal.h b/drivers/misc/mods/mods_internal.h index 6f8e79ac..e2c012ea 100644 --- a/drivers/misc/mods/mods_internal.h +++ b/drivers/misc/mods/mods_internal.h @@ -502,6 +502,10 @@ int esc_mods_acpi_get_ddc_2(struct mods_client *client, struct MODS_ACPI_GET_DDC_2 *p); int esc_mods_get_acpi_dev_children(struct mods_client *client, 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 /* 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); int esc_mods_pci_reset_function(struct mods_client *client, 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 /* 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); int esc_mods_dma_request_channel(struct mods_client *client, struct MODS_DMA_HANDLE *p); -int esc_mods_dma_request_channel_2(struct mods_client *client, - struct MODS_DMA_HANDLE_2 *p_handle_2); +int esc_mods_dma_request_channel_2(struct mods_client *client, + struct MODS_DMA_HANDLE_2 *p_handle_2); int esc_mods_dma_release_channel(struct mods_client *client, struct MODS_DMA_HANDLE *p); int esc_mods_dma_set_config(struct mods_client *client, diff --git a/drivers/misc/mods/mods_krnl.c b/drivers/misc/mods/mods_krnl.c index 754d97a3..33e477ec 100644 --- a/drivers/misc/mods/mods_krnl.c +++ b/drivers/misc/mods/mods_krnl.c @@ -2029,6 +2029,14 @@ static long mods_krnl_ioctl(struct file *fp, esc_mods_pci_reset_function, mods_pci_dev_2); 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 case MODS_ESC_ALLOC_PAGES: @@ -2257,8 +2265,17 @@ static long mods_krnl_ioctl(struct file *fp, case 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; + +#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 case MODS_ESC_EVAL_ACPI_METHOD: /* fallthrough */ @@ -2437,7 +2454,7 @@ static long mods_krnl_ioctl(struct file *fp, MODS_DMA_TX_DESC); break; 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, MODS_DMA_WAIT_DESC); break; diff --git a/drivers/misc/mods/mods_pci.c b/drivers/misc/mods/mods_pci.c index 0b72200b..8d990f56 100644 --- a/drivers/misc/mods/mods_pci.c +++ b/drivers/misc/mods/mods_pci.c @@ -21,11 +21,14 @@ #include "mods_internal.h" #include +#if defined(MODS_HAS_DMA_OPS) +#include +#endif #include #include #include -#if defined(MODS_HAS_DMA_OPS) -#include +#if KERNEL_VERSION(3, 19, 0) <= MODS_KERNEL_VERSION +#include #endif int mods_is_pci_dev(struct pci_dev *dev, @@ -1006,3 +1009,57 @@ error: return -EINVAL; #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 diff --git a/include/uapi/misc/mods.h b/include/uapi/misc/mods.h index dba23884..ec4c01e5 100644 --- a/include/uapi/misc/mods.h +++ b/include/uapi/misc/mods.h @@ -1,6 +1,6 @@ /* 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. * @@ -1639,7 +1639,6 @@ struct MODS_DMA_HANDLE_2 { char ctrl_dir[MODS_DMA_HANDLE_CTRL_DIR_LEN]; }; - enum MODS_DMA_TRANSFER_DIRECTION { MODS_DMA_MEM_TO_MEM, MODS_DMA_MEM_TO_DEV, @@ -1861,6 +1860,39 @@ struct MODS_TEGRA_OIST_STATUS { #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) #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_OIST_STATUS MODSIO(WR, 140, MODS_TEGRA_OIST_STATUS) #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_ */