From 7a8a0731ae301ce720d1556c5b93efd8352a3ce3 Mon Sep 17 00:00:00 2001 From: Chris Dragan Date: Tue, 10 Jan 2023 01:54:36 -0800 Subject: [PATCH] misc: mods: update from Perforce Bug 3928853 Change-Id: I813a78c92deb516844d67940e34d3f0e5303e96b Signed-off-by: Chris Dragan Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2840673 Reviewed-by: svcacv Reviewed-by: svc-mobile-coverity Reviewed-by: svc-mobile-cert Reviewed-by: svc_kernel_abi Reviewed-by: Sachin Nikam GVS: Gerrit_Virtual_Submit --- drivers/misc/mods/mods_config.h | 9 +-- drivers/misc/mods/mods_internal.h | 21 +++-- drivers/misc/mods/mods_krnl.c | 124 +++++++++++++++++------------- drivers/misc/mods/mods_mem.c | 8 +- drivers/misc/mods/mods_pci.c | 71 ++++++++--------- drivers/misc/mods/mods_smmu_drv.c | 2 +- 6 files changed, 126 insertions(+), 109 deletions(-) diff --git a/drivers/misc/mods/mods_config.h b/drivers/misc/mods/mods_config.h index 962a80ed..b4d9615c 100644 --- a/drivers/misc/mods/mods_config.h +++ b/drivers/misc/mods/mods_config.h @@ -88,7 +88,6 @@ #endif #if KERNEL_VERSION(4, 13, 0) <= MODS_KERNEL_VERSION -# define MODS_HAS_FLR_SUPPORT # define MODS_HAS_SET_MEMORY_HEADER 1 #endif @@ -100,10 +99,6 @@ # define MODS_HAS_POLL_T 1 #endif -#if KERNEL_VERSION(4, 17, 0) <= MODS_KERNEL_VERSION -# 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 @@ -116,8 +111,8 @@ # define MODS_ENABLE_BPMP_MRQ_API 1 #endif -#if KERNEL_VERSION(5, 10, 0) <= MODS_KERNEL_VERSION -# define MODS_HAS_ACPI_MATCH_DATA 1 +#if KERNEL_VERSION(6, 1, 0) > MODS_KERNEL_VERSION +# define MODS_HAS_FB_SET_SUSPEND 1 #endif #endif /* _MODS_CONFIG_H_ */ diff --git a/drivers/misc/mods/mods_internal.h b/drivers/misc/mods/mods_internal.h index a93793d2..55de8672 100644 --- a/drivers/misc/mods/mods_internal.h +++ b/drivers/misc/mods/mods_internal.h @@ -2,7 +2,7 @@ /* * This file is part of NVIDIA MODS kernel driver. * - * Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2008-2023, NVIDIA CORPORATION. All rights reserved. * * NVIDIA MODS kernel driver is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License, @@ -261,7 +261,7 @@ struct NVL_TRAINED { #define DEBUG_TEGRADMA 0x400 #define DEBUG_ISR_DETAILED (DEBUG_ISR | DEBUG_DETAILED) #define DEBUG_MEM_DETAILED (DEBUG_MEM | DEBUG_DETAILED) -#define DEBUG_ALL (DEBUG_IOCTL | DEBUG_PCI | DEBUG_ACPI | \ +#define DEBUG_ALL (DEBUG_IOCTL | DEBUG_PCI | DEBUG_ACPI | \ DEBUG_ISR | DEBUG_MEM | DEBUG_FUNC | DEBUG_CLOCK | DEBUG_DETAILED | \ DEBUG_TEGRADC | DEBUG_TEGRADMA) @@ -372,6 +372,12 @@ struct mods_priv { # define MODS_SG_UNMARK_END(sg) ({(sg)->page_link &= ~2; }) #endif +#if KERNEL_VERSION(5, 11, 0) <= MODS_KERNEL_VERSION +# define MODS_KMAP kmap_local_page +#else +# define MODS_KMAP kmap +#endif + /* ************************************************************************* */ /* ** MODULE WIDE FUNCTIONS */ /* ************************************************************************* */ @@ -711,7 +717,6 @@ int esc_mods_send_trustzone_msg(struct mods_client *client, int esc_mods_invoke_optee_ta(struct mods_client *client, struct MODS_OPTEE_PARAMS *p); #endif - #endif /* MODS SP call */ @@ -750,11 +755,6 @@ void smmu_driver_exit(void); int esc_mods_send_ipi(struct mods_client *client, struct MODS_SEND_IPI *p); #endif -#if defined(CONFIG_ARM_FFA_TRANSPORT) -int mods_ffa_abi_register(void); -void mods_ffa_abi_unregister(void); -#endif - #if defined(CONFIG_TEGRA_IVC) int esc_mods_bpmp_uphy_lane_eom_scan(struct mods_client *client, struct MODS_BPMP_UPHY_LANE_EOM_SCAN_PARAMS *p); @@ -765,4 +765,9 @@ int mods_bpmpipc_init(struct mods_client *client, void mods_bpmpipc_cleanup(void); #endif +#if defined(CONFIG_ARM_FFA_TRANSPORT) +int mods_ffa_abi_register(void); +void mods_ffa_abi_unregister(void); +#endif + #endif /* _MODS_INTERNAL_H_ */ diff --git a/drivers/misc/mods/mods_krnl.c b/drivers/misc/mods/mods_krnl.c index 526cc8fd..a6862152 100644 --- a/drivers/misc/mods/mods_krnl.c +++ b/drivers/misc/mods/mods_krnl.c @@ -2,7 +2,7 @@ /* * This file is part of NVIDIA MODS kernel driver. * - * Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2008-2023, NVIDIA CORPORATION. All rights reserved. * * NVIDIA MODS kernel driver is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License, @@ -485,7 +485,6 @@ static int __init mods_init_module(void) if (rc < 0) return rc; #endif - #endif #if defined(CONFIG_ARM_FFA_TRANSPORT) @@ -920,7 +919,7 @@ static int mods_krnl_vma_access(struct vm_area_struct *vma, if (map_offs + len > PAGE_SIZE) len = (int)(PAGE_SIZE - map_offs); - ptr = kmap(p_page); + ptr = MODS_KMAP(p_page); if (ptr) { char *bptr = (char *)ptr + map_offs; @@ -1336,7 +1335,7 @@ static int esc_mods_get_screen_info(struct mods_client *client, static int esc_mods_get_screen_info_2(struct mods_client *client, struct MODS_SCREEN_INFO_2 *p) { -#if defined(CONFIG_FB) +#if defined(CONFIG_FB) && defined(MODS_HAS_FB_SET_SUSPEND) unsigned int i; bool found = false; #endif @@ -1349,7 +1348,7 @@ static int esc_mods_get_screen_info_2(struct mods_client *client, p->ext_lfb_base = 0; #endif -#if defined(CONFIG_FB) +#if defined(CONFIG_FB) && defined(MODS_HAS_FB_SET_SUSPEND) if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) return OK; @@ -1361,7 +1360,8 @@ static int esc_mods_get_screen_info_2(struct mods_client *client, * in use by the console and potentially using it themselves. * For an EFI console, pull the FB base address from the FB - * driver registered_fb data instead of screen_info + * driver registered_fb data instead of screen_info. + * Note: on kernel 6.1 and up registered_fb is not available. */ for (i = 0; i < ARRAY_SIZE(registered_fb); i++) { bool skipped = true; @@ -1390,6 +1390,68 @@ static int esc_mods_get_screen_info_2(struct mods_client *client, #endif #if defined(MODS_HAS_CONSOLE_LOCK) + +#if defined(CONFIG_FB) && defined(MODS_HAS_FB_SET_SUSPEND) +static int suspend_fb(struct mods_client *client) +{ + unsigned int i; + int err = -EINVAL; + + /* tell the os to block fb accesses */ + for (i = 0; i < ARRAY_SIZE(registered_fb); i++) { + bool suspended = false; + + if (!registered_fb[i]) + continue; + + console_lock(); + if (registered_fb[i]->state != FBINFO_STATE_SUSPENDED) { + fb_set_suspend(registered_fb[i], 1); + client->mods_fb_suspended[i] = 1; + suspended = true; + } + console_unlock(); + err = OK; + + if (suspended) + cl_info("suspended fb%u '%s'\n", i, + registered_fb[i]->fix.id); + } + + return err; +} + +static int resume_fb(struct mods_client *client) +{ + unsigned int i; + int err = -EINVAL; + + for (i = 0; i < ARRAY_SIZE(registered_fb); i++) { + bool resumed = false; + + if (!registered_fb[i]) + continue; + + console_lock(); + if (client->mods_fb_suspended[i]) { + fb_set_suspend(registered_fb[i], 0); + client->mods_fb_suspended[i] = 0; + resumed = true; + } + console_unlock(); + err = OK; + + if (resumed) + cl_info("resumed fb%u\n", i); + } + + return err; +} +#else +#define suspend_fb(client) (-EINVAL) +#define resume_fb(client) (-EINVAL) +#endif + static atomic_t console_is_locked; static int esc_mods_lock_console(struct mods_client *client) @@ -1419,9 +1481,6 @@ static int esc_mods_unlock_console(struct mods_client *client) static int esc_mods_suspend_console(struct mods_client *client) { int err = -EINVAL; -#if defined(CONFIG_FB) - unsigned int i; -#endif LOG_ENT(); @@ -1431,28 +1490,7 @@ static int esc_mods_suspend_console(struct mods_client *client) return -EINVAL; } -#if defined(CONFIG_FB) - /* tell the os to block fb accesses */ - for (i = 0; i < ARRAY_SIZE(registered_fb); i++) { - bool suspended = false; - - if (!registered_fb[i]) - continue; - - console_lock(); - if (registered_fb[i]->state != FBINFO_STATE_SUSPENDED) { - fb_set_suspend(registered_fb[i], 1); - client->mods_fb_suspended[i] = 1; - suspended = true; - } - console_unlock(); - err = OK; - - if (suspended) - cl_info("suspended fb%u '%s'\n", i, - registered_fb[i]->fix.id); - } -#endif + err = suspend_fb(client); #if defined(MODS_HAS_CONSOLE_BINDING) if (&vga_con == vc_cons[fg_console].d->vc_sw) { @@ -1486,9 +1524,6 @@ static int esc_mods_resume_console(struct mods_client *client) static int mods_resume_console(struct mods_client *client) { int err = -EINVAL; -#if defined(CONFIG_FB) - unsigned int i; -#endif LOG_ENT(); @@ -1501,26 +1536,7 @@ static int mods_resume_console(struct mods_client *client) return -EINVAL; } -#if defined(CONFIG_FB) - for (i = 0; i < ARRAY_SIZE(registered_fb); i++) { - bool resumed = false; - - if (!registered_fb[i]) - continue; - - console_lock(); - if (client->mods_fb_suspended[i]) { - fb_set_suspend(registered_fb[i], 0); - client->mods_fb_suspended[i] = 0; - resumed = true; - } - console_unlock(); - err = OK; - - if (resumed) - cl_info("resumed fb%u\n", i); - } -#endif + err = resume_fb(client); #if defined(MODS_HAS_CONSOLE_BINDING) if (&dummy_con == vc_cons[fg_console].d->vc_sw) { diff --git a/drivers/misc/mods/mods_mem.c b/drivers/misc/mods/mods_mem.c index a6c9e6a8..f896705b 100644 --- a/drivers/misc/mods/mods_mem.c +++ b/drivers/misc/mods/mods_mem.c @@ -2,7 +2,7 @@ /* * This file is part of NVIDIA MODS kernel driver. * - * Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2008-2023, NVIDIA CORPORATION. All rights reserved. * * NVIDIA MODS kernel driver is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License, @@ -430,7 +430,7 @@ static int setup_cache_attr(struct mods_client *client, for (offs = 0; offs < sg->length; offs += PAGE_SIZE) { void *ptr; - ptr = kmap(sg_page(sg) + (offs >> PAGE_SHIFT)); + ptr = MODS_KMAP(sg_page(sg) + (offs >> PAGE_SHIFT)); if (unlikely(!ptr)) { cl_error("kmap failed\n"); return -ENOMEM; @@ -556,7 +556,7 @@ static int restore_cache_one_chunk(struct page *p_page, u8 order) u32 i; for (i = 0; i < num_pages; i++) { - void *ptr = kmap(p_page + i); + void *ptr = MODS_KMAP(p_page + i); int err = -ENOMEM; if (likely(ptr)) @@ -2556,7 +2556,7 @@ static void clear_entry_cache_mappings(struct mods_client *client, u32 i_page = chunk_offs >> PAGE_SHIFT; u32 page_offs = chunk_offs - (i_page << PAGE_SHIFT); u64 page_va = - (u64)(size_t)kmap(sg_page(sg) + i_page); + (u64)(size_t)MODS_KMAP(sg_page(sg) + i_page); u64 clear_va = page_va + page_offs; u64 clear_pa = sg_phys(sg) + chunk_offs; u32 clear_size = PAGE_SIZE - page_offs; diff --git a/drivers/misc/mods/mods_pci.c b/drivers/misc/mods/mods_pci.c index 338b08fe..fb3c90a0 100644 --- a/drivers/misc/mods/mods_pci.c +++ b/drivers/misc/mods/mods_pci.c @@ -2,7 +2,7 @@ /* * This file is part of NVIDIA MODS kernel driver. * - * Copyright (c) 2008-2022, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2008-2023, NVIDIA CORPORATION. All rights reserved. * * NVIDIA MODS kernel driver is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License, @@ -27,6 +27,9 @@ #include #include #include +#if KERNEL_VERSION(2, 32, 0) <= MODS_KERNEL_VERSION +#include +#endif #if KERNEL_VERSION(3, 19, 0) <= MODS_KERNEL_VERSION #include #endif @@ -1009,14 +1012,32 @@ int esc_mods_pci_set_dma_mask(struct mods_client *client, return err; } +static int check_flr(struct pci_dev *dev) +{ + int cap_pos; + u32 cap; + +#if KERNEL_VERSION(4, 12, 0) <= MODS_KERNEL_VERSION + if (dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) + return -ENOTTY; +#endif + + cap_pos = pci_find_capability(dev, PCI_CAP_ID_EXP); + if (!cap_pos) + return -ENOTTY; + + pci_read_config_dword(dev, cap_pos + PCI_EXP_DEVCAP, &cap); + if (!(cap & PCI_EXP_DEVCAP_FLR)) + return -ENOTTY; + + return 0; +} + int esc_mods_pci_reset_function(struct mods_client *client, struct mods_pci_dev_2 *pcidev) { -#if defined(MODS_HAS_FLR_SUPPORT) - int err; struct pci_dev *dev; - u32 cap; - const struct pci_error_handlers *err_handler; + int err; LOG_ENT(); @@ -1032,32 +1053,26 @@ int esc_mods_pci_reset_function(struct mods_client *client, return err; } - pcie_capability_read_dword(dev, PCI_EXP_DEVCAP, &cap); - if ((dev->dev_flags & PCI_DEV_FLAGS_NO_FLR_RESET) || - !(cap & PCI_EXP_DEVCAP_FLR)) { + err = check_flr(dev); + if (unlikely(err)) { cl_error( "function level reset not supported on dev %04x:%02x:%02x.%x\n", pcidev->domain, pcidev->bus, pcidev->device, pcidev->function); - err = -ENOTTY; goto error; } - pci_cfg_access_lock(dev); - device_lock(&dev->dev); +#if KERNEL_VERSION(2, 32, 0) <= MODS_KERNEL_VERSION + pm_runtime_get_sync(&dev->dev); +#endif - err_handler = dev->driver ? dev->driver->err_handler : NULL; - if (err_handler && err_handler->reset_prepare) - err_handler->reset_prepare(dev); + err = pci_reset_function(dev); - pci_set_power_state(dev, PCI_D0); - pci_save_state(dev); - pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE); - -#if defined(MODS_PCIE_FLR_HAS_ERR) - err = pcie_flr(dev); +#if KERNEL_VERSION(2, 32, 0) <= MODS_KERNEL_VERSION + pm_runtime_put(&dev->dev); +#endif if (unlikely(err)) cl_error("pcie_flr failed on dev %04x:%02x:%02x.%x\n", @@ -1065,31 +1080,17 @@ int esc_mods_pci_reset_function(struct mods_client *client, pcidev->bus, pcidev->device, pcidev->function); -#else - pcie_flr(dev); -#endif - - if (!err) + else cl_info("pcie_flr succeeded on dev %04x:%02x:%02x.%x\n", pcidev->domain, pcidev->bus, pcidev->device, pcidev->function); - pci_restore_state(dev); - - if (err_handler && err_handler->reset_done) - err_handler->reset_done(dev); - - device_unlock(&dev->dev); - pci_cfg_access_unlock(dev); error: pci_dev_put(dev); LOG_EXT(); return err; -#else - return -EINVAL; -#endif } #ifdef MODS_HAS_DEV_PROPS diff --git a/drivers/misc/mods/mods_smmu_drv.c b/drivers/misc/mods/mods_smmu_drv.c index d7768181..9d2134b1 100644 --- a/drivers/misc/mods/mods_smmu_drv.c +++ b/drivers/misc/mods/mods_smmu_drv.c @@ -80,7 +80,7 @@ static int mods_smmu_driver_probe(struct platform_device *pdev) } } else { -#if MODS_HAS_ACPI_MATCH_DATA +#if KERNEL_VERSION(5, 10, 0) <= MODS_KERNEL_VERSION dev_name = (const char *)acpi_device_get_match_data(dev); #endif if (!dev_name) {