From ca09591fbd213d521feaf1856b41e887b2906a01 Mon Sep 17 00:00:00 2001 From: Bernhard Stoeckner Date: Thu, 16 Jan 2025 17:31:43 +0100 Subject: [PATCH] 550.144.03 --- README.md | 6 +- kernel-open/Kbuild | 2 +- kernel-open/conftest.sh | 134 +++- kernel-open/header-presence-tests.mk | 5 +- kernel-open/nvidia-drm/nvidia-drm-conftest.h | 7 + kernel-open/nvidia-drm/nvidia-drm-drv.c | 26 +- kernel-open/nvidia-drm/nvidia-drm-sources.mk | 3 + kernel-open/nvidia-uvm/uvm_hmm.c | 29 +- kernel-open/nvidia/internal_crypt_lib.h | 4 +- kernel-open/nvidia/libspdm_ecc.c | 136 +++- kernel-open/nvidia/nv.c | 4 + kernel-open/nvidia/nvidia.Kbuild | 3 + src/common/inc/nvBldVer.h | 20 +- src/common/inc/nvUnixVersion.h | 2 +- .../ampere/ga100/dev_nv_pcfg_xve_regmap.h | 71 ++ .../nvswitch/kernel/ls10/multicast_ls10.c | 661 +++--------------- src/nvidia/generated/g_kernel_bif_nvoc.c | 6 +- src/nvidia/generated/g_kernel_bif_nvoc.h | 2 + .../gpu/bif/arch/ampere/kernel_bif_ga100.c | 58 ++ src/nvidia/src/kernel/gpu/fifo/kernel_fifo.c | 23 +- .../libraries/nvport/string/string_generic.c | 28 +- version.mk | 2 +- 22 files changed, 590 insertions(+), 642 deletions(-) create mode 100644 src/common/inc/swref/published/ampere/ga100/dev_nv_pcfg_xve_regmap.h diff --git a/README.md b/README.md index 4eec4126f..07518d24f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # NVIDIA Linux Open GPU Kernel Module Source This is the source release of the NVIDIA Linux open GPU kernel modules, -version 550.142. +version 550.144.03. ## How to Build @@ -17,7 +17,7 @@ as root: Note that the kernel modules built here must be used with GSP firmware and user-space NVIDIA GPU driver components from a corresponding -550.142 driver release. This can be achieved by installing +550.144.03 driver release. This can be achieved by installing the NVIDIA GPU driver from the .run file using the `--no-kernel-modules` option. E.g., @@ -188,7 +188,7 @@ encountered specific to them. For details on feature support and limitations, see the NVIDIA GPU driver end user README here: -https://us.download.nvidia.com/XFree86/Linux-x86_64/550.142/README/kernel_open.html +https://us.download.nvidia.com/XFree86/Linux-x86_64/550.144.03/README/kernel_open.html For vGPU support, please refer to the README.vgpu packaged in the vGPU Host Package for more details. diff --git a/kernel-open/Kbuild b/kernel-open/Kbuild index c2112c884..71bb411b6 100644 --- a/kernel-open/Kbuild +++ b/kernel-open/Kbuild @@ -86,7 +86,7 @@ EXTRA_CFLAGS += -I$(src)/common/inc EXTRA_CFLAGS += -I$(src) EXTRA_CFLAGS += -Wall $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-format-extra-args EXTRA_CFLAGS += -D__KERNEL__ -DMODULE -DNVRM -EXTRA_CFLAGS += -DNV_VERSION_STRING=\"550.142\" +EXTRA_CFLAGS += -DNV_VERSION_STRING=\"550.144.03\" ifneq ($(SYSSRCHOST1X),) EXTRA_CFLAGS += -I$(SYSSRCHOST1X) diff --git a/kernel-open/conftest.sh b/kernel-open/conftest.sh index cd478625c..d33e16d87 100755 --- a/kernel-open/conftest.sh +++ b/kernel-open/conftest.sh @@ -5583,6 +5583,23 @@ compile_test() { else echo "#undef NV_OF_PROPERTY_READ_VARIABLE_U32_ARRAY_PRESENT" | append_conftest "functions" fi + ;; + + module_import_ns_takes_string_literal) + # + # Determine if the MODULE_IMPORT_NS macro takes a string literal + # or constant. + # + # Commit cdd30ebb1b9f ("module: Convert symbol namespace to + # string literal") changed MODULE_IMPORT_NS to take a string + # literal in Linux kernel v6.13. + # + CODE=" + #include + + MODULE_IMPORT_NS(DMA_BUF);" + + compile_check_conftest "$CODE" "NV_MODULE_IMPORT_NS_TAKES_STRING_LITERAL" "" "functions" ;; devm_of_platform_populate) @@ -6616,7 +6633,8 @@ compile_test() { # Determine whether drm_fbdev_ttm_setup is present. # # Added by commit aae4682e5d66 ("drm/fbdev-generic: - # Convert to fbdev-ttm") in v6.11. + # Convert to fbdev-ttm") in v6.11. Removed by commit + # 1000634477d8 ("drm/fbdev-ttm:Convert to client-setup") in v6.13. # CODE=" #include @@ -6630,6 +6648,25 @@ compile_test() { compile_check_conftest "$CODE" "NV_DRM_FBDEV_TTM_SETUP_PRESENT" "" "functions" ;; + drm_client_setup) + # + # Determine whether drm_client_setup is present. + # + # Added by commit d07fdf922592 ("drm/fbdev-ttm: + # Convert to client-setup") in v6.13. + # + CODE=" + #include + #if defined(NV_DRM_DRM_CLIENT_SETUP_H_PRESENT) + #include + #endif + void conftest_drm_client_setup(void) { + drm_client_setup(); + }" + + compile_check_conftest "$CODE" "NV_DRM_CLIENT_SETUP_PRESENT" "" "functions" + ;; + drm_output_poll_changed) # # Determine whether drm_mode_config_funcs.output_poll_changed @@ -6653,6 +6690,38 @@ compile_test() { compile_check_conftest "$CODE" "NV_DRM_OUTPUT_POLL_CHANGED_PRESENT" "" "types" ;; + aperture_remove_conflicting_devices) + # + # Determine whether aperture_remove_conflicting_devices is present. + # + # Added by commit 7283f862bd991 ("drm: Implement DRM aperture + # helpers under video/") in v6.0 + CODE=" + #if defined(NV_LINUX_APERTURE_H_PRESENT) + #include + #endif + void conftest_aperture_remove_conflicting_devices(void) { + aperture_remove_conflicting_devices(); + }" + compile_check_conftest "$CODE" "NV_APERTURE_REMOVE_CONFLICTING_DEVICES_PRESENT" "" "functions" + ;; + + aperture_remove_conflicting_pci_devices) + # + # Determine whether aperture_remove_conflicting_pci_devices is present. + # + # Added by commit 7283f862bd991 ("drm: Implement DRM aperture + # helpers under video/") in v6.0 + CODE=" + #if defined(NV_LINUX_APERTURE_H_PRESENT) + #include + #endif + void conftest_aperture_remove_conflicting_pci_devices(void) { + aperture_remove_conflicting_pci_devices(); + }" + compile_check_conftest "$CODE" "NV_APERTURE_REMOVE_CONFLICTING_PCI_DEVICES_PRESENT" "" "functions" + ;; + drm_aperture_remove_conflicting_pci_framebuffers) # # Determine whether drm_aperture_remove_conflicting_pci_framebuffers is present. @@ -6746,17 +6815,17 @@ compile_test() { # This test is not complete and may return false positive. # CODE=" - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include void conftest_crypto(void) { struct shash_desc sd; struct crypto_shash cs; @@ -6766,6 +6835,47 @@ compile_test() { compile_check_conftest "$CODE" "NV_CRYPTO_PRESENT" "" "symbols" ;; + crypto_akcipher_verify) + # + # Determine whether the crypto_akcipher_verify API is still present. + # It was removed by commit 6b34562 ('crypto: akcipher - Drop sign/verify operations') + # in v6.13-rc1 (2024-10-04). + # + # This test is dependent on the crypto conftest to determine whether crypto should be + # enabled at all. That means that if the kernel is old enough such that crypto_akcipher_verify + # + # The test merely checks for the presence of the API, as it assumes that if the API + # is no longer present, the new API to replace it (crypto_sig_verify) must be present. + # If the kernel version is too old to have crypto_akcipher_verify, it will fail the crypto + # conftest above and all crypto code will be compiled out. + # + CODE=" + #include + #include + void conftest_crypto_akcipher_verify(void) { + (void)crypto_akcipher_verify; + }" + + compile_check_conftest "$CODE" "NV_CRYPTO_AKCIPHER_VERIFY_PRESENT" "" "symbols" + ;; + + ecc_digits_from_bytes) + # + # Determine whether ecc_digits_from_bytes is present. + # It was added in commit c6ab5c915da4 ('crypto: ecc - Prevent ecc_digits_from_bytes from + # reading too many bytes') in v6.10. + # + # This functionality is needed when crypto_akcipher_verify is not present. + # + CODE=" + #include + void conftest_ecc_digits_from_bytes(void) { + (void)ecc_digits_from_bytes; + }" + + compile_check_conftest "$CODE" "NV_ECC_DIGITS_FROM_BYTES_PRESENT" "" "symbols" + ;; + mempolicy_has_unified_nodes) # # Determine if the 'mempolicy' structure has diff --git a/kernel-open/header-presence-tests.mk b/kernel-open/header-presence-tests.mk index 7009cc37c..c5e7f7e9a 100644 --- a/kernel-open/header-presence-tests.mk +++ b/kernel-open/header-presence-tests.mk @@ -16,6 +16,7 @@ NV_HEADER_PRESENCE_TESTS = \ drm/drm_drv.h \ drm/drm_fbdev_generic.h \ drm/drm_fbdev_ttm.h \ + drm/drm_client_setup.h \ drm/drm_framebuffer.h \ drm/drm_connector.h \ drm/drm_probe_helper.h \ @@ -33,6 +34,7 @@ NV_HEADER_PRESENCE_TESTS = \ generated/autoconf.h \ generated/compile.h \ generated/utsrelease.h \ + linux/aperture.h \ linux/efi.h \ linux/kconfig.h \ linux/platform/tegra/mc_utils.h \ @@ -99,5 +101,6 @@ NV_HEADER_PRESENCE_TESTS = \ linux/cc_platform.h \ asm/cpufeature.h \ linux/mpi.h \ - asm/mshyperv.h + asm/mshyperv.h \ + crypto/sig.h diff --git a/kernel-open/nvidia-drm/nvidia-drm-conftest.h b/kernel-open/nvidia-drm/nvidia-drm-conftest.h index 552c2c970..561e39cc5 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-conftest.h +++ b/kernel-open/nvidia-drm/nvidia-drm-conftest.h @@ -62,6 +62,13 @@ #undef NV_DRM_FENCE_AVAILABLE #endif +#if defined(NV_DRM_CLIENT_SETUP_PRESENT) && \ + (defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_PRESENT) || \ + defined(NV_APERTURE_REMOVE_CONFLICTING_PCI_DEVICES_PRESENT)) +#define NV_DRM_FBDEV_AVAILABLE +#define NV_DRM_CLIENT_AVAILABLE +#endif + /* * We can support color management if either drm_helper_crtc_enable_color_mgmt() * or drm_crtc_enable_color_mgmt() exist. diff --git a/kernel-open/nvidia-drm/nvidia-drm-drv.c b/kernel-open/nvidia-drm/nvidia-drm-drv.c index 481220946..fdc9331fd 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-drv.c +++ b/kernel-open/nvidia-drm/nvidia-drm-drv.c @@ -64,11 +64,22 @@ #include #endif -#if defined(NV_DRM_FBDEV_AVAILABLE) +#if defined(NV_LINUX_APERTURE_H_PRESENT) +#include +#endif + +#if defined(NV_DRM_DRM_APERTURE_H_PRESENT) #include +#endif + +#if defined(NV_DRM_FBDEV_AVAILABLE) #include #endif +#if defined(NV_DRM_DRM_CLIENT_SETUP_H_PRESENT) +#include +#endif + #if defined(NV_DRM_DRM_FBDEV_TTM_H_PRESENT) #include #elif defined(NV_DRM_DRM_FBDEV_GENERIC_H_PRESENT) @@ -1726,6 +1737,9 @@ static struct drm_driver nv_drm_driver = { #elif defined(NV_DRM_DRIVER_HAS_LEGACY_DEV_LIST) .legacy_dev_list = LIST_HEAD_INIT(nv_drm_driver.legacy_dev_list), #endif +#if defined(DRM_FBDEV_TTM_DRIVER_OPS) + DRM_FBDEV_TTM_DRIVER_OPS, +#endif }; @@ -1827,13 +1841,21 @@ void nv_drm_register_drm_device(const nv_gpu_info_t *gpu_info) if (bus_is_pci) { struct pci_dev *pdev = to_pci_dev(device); +#if defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_PRESENT) + #if defined(NV_DRM_APERTURE_REMOVE_CONFLICTING_PCI_FRAMEBUFFERS_HAS_DRIVER_ARG) drm_aperture_remove_conflicting_pci_framebuffers(pdev, &nv_drm_driver); #else drm_aperture_remove_conflicting_pci_framebuffers(pdev, nv_drm_driver.name); #endif + +#elif defined(NV_APERTURE_REMOVE_CONFLICTING_PCI_DEVICES_PRESENT) + aperture_remove_conflicting_pci_devices(pdev, nv_drm_driver.name); +#endif } - #if defined(NV_DRM_FBDEV_TTM_AVAILABLE) + #if defined(NV_DRM_CLIENT_AVAILABLE) + drm_client_setup(dev, NULL); + #elif defined(NV_DRM_FBDEV_TTM_AVAILABLE) drm_fbdev_ttm_setup(dev, 32); #elif defined(NV_DRM_FBDEV_GENERIC_AVAILABLE) drm_fbdev_generic_setup(dev, 32); diff --git a/kernel-open/nvidia-drm/nvidia-drm-sources.mk b/kernel-open/nvidia-drm/nvidia-drm-sources.mk index fb3654c86..8ab697345 100644 --- a/kernel-open/nvidia-drm/nvidia-drm-sources.mk +++ b/kernel-open/nvidia-drm/nvidia-drm-sources.mk @@ -66,8 +66,11 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += dma_fence_set_error NV_CONFTEST_FUNCTION_COMPILE_TESTS += fence_set_error NV_CONFTEST_FUNCTION_COMPILE_TESTS += sync_file_get_fence NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_aperture_remove_conflicting_pci_framebuffers +NV_CONFTEST_FUNCTION_COMPILE_TESTS += aperture_remove_conflicting_devices +NV_CONFTEST_FUNCTION_COMPILE_TESTS += aperture_remove_conflicting_pci_devices NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_fbdev_generic_setup NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_fbdev_ttm_setup +NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_client_setup NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_connector_attach_hdr_output_metadata_property NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_helper_crtc_enable_color_mgmt NV_CONFTEST_FUNCTION_COMPILE_TESTS += drm_crtc_enable_color_mgmt diff --git a/kernel-open/nvidia-uvm/uvm_hmm.c b/kernel-open/nvidia-uvm/uvm_hmm.c index 977bd7a12..49598cff5 100644 --- a/kernel-open/nvidia-uvm/uvm_hmm.c +++ b/kernel-open/nvidia-uvm/uvm_hmm.c @@ -163,7 +163,7 @@ static uvm_va_block_t *hmm_va_block_from_node(uvm_range_tree_node_t *node) // Copies the contents of the source device-private page to the // destination CPU page. This will invalidate mappings, so cannot be // called while holding any va_block locks. -static void hmm_copy_devmem_page(struct page *dst_page, struct page *src_page) +static NV_STATUS hmm_copy_devmem_page(struct page *dst_page, struct page *src_page) { uvm_tracker_t tracker = UVM_TRACKER_INIT(); uvm_gpu_phys_address_t src_addr; @@ -207,7 +207,7 @@ static void hmm_copy_devmem_page(struct page *dst_page, struct page *src_page) uvm_push_end(&push); status = uvm_tracker_add_push_safe(&tracker, &push); if (status == NV_OK) - uvm_tracker_wait_deinit(&tracker); + status = uvm_tracker_wait_deinit(&tracker); out_unmap_cpu: uvm_parent_gpu_unmap_cpu_pages(gpu->parent, dma_addr, PAGE_SIZE); @@ -216,12 +216,7 @@ out_unmap_gpu: uvm_mmu_chunk_unmap(gpu_chunk, NULL); out: - // We can't fail eviction because we need to free the device-private pages - // so the GPU can be unregistered. So the best we can do is warn on any - // failures and zero the uninitialised page. This could result in data loss - // in the application but failures are not expected. - if (WARN_ON(status != NV_OK)) - memzero_page(dst_page, 0, PAGE_SIZE); + return status; } static NV_STATUS uvm_hmm_pmm_gpu_evict_pfn(unsigned long pfn) @@ -246,7 +241,12 @@ static NV_STATUS uvm_hmm_pmm_gpu_evict_pfn(unsigned long pfn) lock_page(dst_page); - hmm_copy_devmem_page(dst_page, migrate_pfn_to_page(src_pfn)); + // We can't fail eviction because we need to free the device-private + // pages so the GPU can be unregistered. So the best we can do is warn + // on any failures and zero the uninitialized page. This could result + // in data loss in the application but failures are not expected. + if (hmm_copy_devmem_page(dst_page, migrate_pfn_to_page(src_pfn)) != NV_OK) + memzero_page(dst_page, 0, PAGE_SIZE); dst_pfn = migrate_pfn(page_to_pfn(dst_page)); migrate_device_pages(&src_pfn, &dst_pfn, 1); } @@ -3487,12 +3487,17 @@ NV_STATUS uvm_hmm_remote_cpu_fault(struct vm_fault *vmf) lock_page(dst_page); dst_pfn = migrate_pfn(page_to_pfn(dst_page)); - hmm_copy_devmem_page(dst_page, src_page); + status = hmm_copy_devmem_page(dst_page, src_page); + if (status != NV_OK) { + unlock_page(dst_page); + __free_page(dst_page); + dst_pfn = 0; + } } - migrate_vma_pages(&args); - out: + if (status == NV_OK) + migrate_vma_pages(&args); migrate_vma_finalize(&args); return status; diff --git a/kernel-open/nvidia/internal_crypt_lib.h b/kernel-open/nvidia/internal_crypt_lib.h index 2eac7d5e4..917acb26d 100644 --- a/kernel-open/nvidia/internal_crypt_lib.h +++ b/kernel-open/nvidia/internal_crypt_lib.h @@ -64,7 +64,9 @@ * old or even just user disabled. If we should use LKCA, include headers, else * define stubs to return errors. */ -#if defined(NV_CRYPTO_PRESENT) && defined (NV_CONFIG_CRYPTO_PRESENT) +#if defined(NV_CRYPTO_PRESENT) && defined (NV_CONFIG_CRYPTO_PRESENT) && \ + (defined(NV_CRYPTO_AKCIPHER_VERIFY_PRESENT) || \ + (defined(NV_CRYPTO_SIG_H_PRESENT) && defined(NV_ECC_DIGITS_FROM_BYTES_PRESENT))) #define USE_LKCA 1 #endif diff --git a/kernel-open/nvidia/libspdm_ecc.c b/kernel-open/nvidia/libspdm_ecc.c index 1f8f0100f..3c0d5c8a8 100644 --- a/kernel-open/nvidia/libspdm_ecc.c +++ b/kernel-open/nvidia/libspdm_ecc.c @@ -1,5 +1,5 @@ /* -* SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +* SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: MIT * * Permission is hereby granted, free of charge, to any person obtaining a @@ -30,14 +30,26 @@ MODULE_SOFTDEP("pre: ecdh_generic,ecdsa_generic"); #include #include #include +#ifndef NV_CRYPTO_AKCIPHER_VERIFY_PRESENT +#include + +struct signature +{ + u64 r[ECC_MAX_DIGITS]; + u64 s[ECC_MAX_DIGITS]; +}; +#endif // NV_CRYPTO_AKCIPHER_VERIFY_PRESENT + +#define ECDSA_PUBKEY_HEADER_XY_PRESENT (0x4) struct ecc_ctx { unsigned int curve_id; u64 priv_key[ECC_MAX_DIGITS]; // In big endian struct { - // ecdsa wants byte preceding pub_key to be set to '4' - u64 pub_key_prefix; + // ecdsa pubkey has header indicating length of pubkey + u8 padding[7]; + u8 pub_key_prefix; u64 pub_key[2 * ECC_MAX_DIGITS]; }; @@ -46,7 +58,7 @@ struct ecc_ctx { char const *name; int size; }; -#endif +#endif // USE_LKCA void *libspdm_ec_new_by_nid(size_t nid) { @@ -77,7 +89,7 @@ void *libspdm_ec_new_by_nid(size_t nid) ctx->priv_key_set = false; return ctx; -#endif +#endif // USE_LKCA } void libspdm_ec_free(void *ec_context) @@ -109,7 +121,7 @@ bool lkca_ecdsa_set_priv_key(void *context, uint8_t *key, size_t key_size) ctx->pub_key_set = true; ctx->priv_key_set = true; return true; -#endif +#endif // USE_LKCA } bool lkca_ec_set_pub_key(void *ec_context, const uint8_t *public_key, @@ -139,7 +151,7 @@ bool lkca_ec_set_pub_key(void *ec_context, const uint8_t *public_key, memcpy(ctx->pub_key, public_key, public_key_size); ctx->pub_key_set = true; return true; -#endif +#endif // USE_LKCA } bool lkca_ec_get_pub_key(void *ec_context, uint8_t *public_key, @@ -158,7 +170,7 @@ bool lkca_ec_get_pub_key(void *ec_context, uint8_t *public_key, memcpy(public_key, ctx->pub_key, ctx->size); return true; -#endif +#endif // USE_LKCA } bool lkca_ec_generate_key(void *ec_context, uint8_t *public_data, @@ -185,7 +197,7 @@ bool lkca_ec_generate_key(void *ec_context, uint8_t *public_data, ctx->pub_key_set = true; return true; -#endif +#endif // USE_LKCA } bool lkca_ec_compute_key(void *ec_context, const uint8_t *peer_public, @@ -218,28 +230,87 @@ bool lkca_ec_compute_key(void *ec_context, const uint8_t *peer_public, *key_size = ctx->size / 2; return true; -#endif +#endif // USE_LKCA } -bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid, - const uint8_t *message_hash, size_t hash_size, - const uint8_t *signature, size_t sig_size) +#ifndef NV_CRYPTO_AKCIPHER_VERIFY_PRESENT +static bool lkca_ecdsa_verify_crypto_sig(void *ec_context, size_t hash_nid, + const uint8_t *message_hash, size_t hash_size, + const uint8_t *signature, size_t sig_size) { #ifndef USE_LKCA return false; -#else +#else // USE_LKCA struct ecc_ctx *ctx = ec_context; + u8 *pub_key; + int err; + DECLARE_CRYPTO_WAIT(wait); + struct crypto_sig * tfm = NULL; + struct signature sig; + + if (sig_size != ctx->size || !ctx->pub_key_set) + { + return false; + } + + tfm = crypto_alloc_sig(ctx->name, CRYPTO_ALG_TYPE_SIG, 0); + if (IS_ERR(tfm)) { + pr_info("crypto_alloc_sig failed in lkca_ecdsa_verify\n"); + return false; + } + + // modify header of pubkey to indicate size + pub_key = (u8 *) &(ctx->pub_key_prefix); + *pub_key = ECDSA_PUBKEY_HEADER_XY_PRESENT; + err = crypto_sig_set_pubkey(tfm, pub_key, ctx->size + 1); + if (err != 0) + { + pr_info("crypto_sig_set_pubkey failed in lkca_ecdsa_verify: %d", -err); + goto failTfm; + } + + // + // Compared to the way we receive the signature, we need to: + // - swap order of all digits + // - swap endianness for each digit + // + memset(&sig, 0, sizeof(sig)); + ecc_digits_from_bytes(signature, ctx->size/2, sig.r, ECC_MAX_DIGITS); + ecc_digits_from_bytes(signature + ctx->size/2, ctx->size/2, sig.s, ECC_MAX_DIGITS); + + err = crypto_sig_verify(tfm, (void *)&sig, sizeof(sig), message_hash, hash_size); + if (err != 0) + { + pr_info("crypto_sig_verify failed in lkca_ecdsa_verify %d\n", -err); + } + +failTfm: + crypto_free_sig(tfm); + + return err == 0; +#endif // USE_LKCA +} + +#else // NV_CRYPTO_AKCIPHER_VERIFY_PRESENT +static bool lkca_ecdsa_verify_akcipher(void *ec_context, size_t hash_nid, + const uint8_t *message_hash, size_t hash_size, + const uint8_t *signature, size_t sig_size) +{ +#ifndef USE_LKCA + return false; +#else // USE_LKCA + struct ecc_ctx *ctx = ec_context; + u8 *pub_key; + int err; + DECLARE_CRYPTO_WAIT(wait); // Roundabout way u64 ber_max_len = 3 + 2 * (4 + (ECC_MAX_BYTES)); u64 ber_len = 0; u8 *ber = NULL; - u8 *pub_key; struct akcipher_request *req = NULL; struct crypto_akcipher *tfm = NULL; struct scatterlist sg; - DECLARE_CRYPTO_WAIT(wait); - int err; if (sig_size != ctx->size) { return false; @@ -251,21 +322,21 @@ bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid, tfm = crypto_alloc_akcipher(ctx->name, CRYPTO_ALG_TYPE_AKCIPHER, 0); if (IS_ERR(tfm)) { - pr_info("ALLOC FAILED\n"); + pr_info("crypto_alloc_akcipher failed in lkca_ecdsa_verify\n"); return false; } - pub_key = (u8 *) ctx->pub_key; - pub_key--; // Go back into byte of pub_key_prefix - *pub_key = 4; // And set it to 4 to placate kernel + // modify header of pubkey to indicate size + pub_key = (u8 *) &(ctx->pub_key_prefix); + *pub_key = ECDSA_PUBKEY_HEADER_XY_PRESENT; if ((err = crypto_akcipher_set_pub_key(tfm, pub_key, ctx->size + 1)) != 0) { - pr_info("SET PUB KEY FAILED: %d\n", -err); + pr_info("crypto_akcipher_set_pub_key failed in lkca_ecdsa_verify: %d\n", -err); goto failTfm; } req = akcipher_request_alloc(tfm, GFP_KERNEL); if (IS_ERR(req)) { - pr_info("REQUEST ALLOC FAILED\n"); + pr_info("akcipher_request_alloc failed in lkca_ecdsa_verify\n"); goto failTfm; } @@ -310,9 +381,8 @@ bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid, CRYPTO_TFM_REQ_MAY_SLEEP, crypto_req_done, &wait); akcipher_request_set_crypt(req, &sg, NULL, ber_len, hash_size); err = crypto_wait_req(crypto_akcipher_verify(req), &wait); - if (err != 0){ - pr_info("Verify FAILED %d\n", -err); + pr_info("crypto_akcipher_verify failed in lkca_ecdsa_verify %d\n", -err); } kfree(ber); @@ -322,5 +392,19 @@ failTfm: crypto_free_akcipher(tfm); return err == 0; -#endif +#endif // USE_LKCA +} +#endif // NV_CRYPTO_AKCIPHER_VERIFY_PRESENT + +bool lkca_ecdsa_verify(void *ec_context, size_t hash_nid, + const uint8_t *message_hash, size_t hash_size, + const uint8_t *signature, size_t sig_size) +{ +#ifndef NV_CRYPTO_AKCIPHER_VERIFY_PRESENT + return lkca_ecdsa_verify_crypto_sig(ec_context, hash_nid, message_hash, hash_size, + signature, sig_size); +#else // NV_CRYPTO_AKCIPHER_VERIFY_PRESENT + return lkca_ecdsa_verify_akcipher(ec_context, hash_nid, message_hash, hash_size, + signature, sig_size); +#endif // NV_CRYPTO_AKCIPHER_VERIFY_PRESENT } diff --git a/kernel-open/nvidia/nv.c b/kernel-open/nvidia/nv.c index ca1cc44bc..626f9cc46 100644 --- a/kernel-open/nvidia/nv.c +++ b/kernel-open/nvidia/nv.c @@ -127,7 +127,11 @@ MODULE_ALIAS_CHARDEV_MAJOR(NV_MAJOR_DEVICE_NUMBER); * DMA_BUF namespace is added by commit id 16b0314aa746 * ("dma-buf: move dma-buf symbols into the DMA_BUF module namespace") in 5.16 */ +#if defined(NV_MODULE_IMPORT_NS_TAKES_STRING_LITERAL) +MODULE_IMPORT_NS("DMA_BUF"); +#else MODULE_IMPORT_NS(DMA_BUF); +#endif #endif // defined(MODULE_IMPORT_NS) const NvBool nv_is_rm_firmware_supported_os = NV_TRUE; diff --git a/kernel-open/nvidia/nvidia.Kbuild b/kernel-open/nvidia/nvidia.Kbuild index 10e53ebbf..5266bfadd 100644 --- a/kernel-open/nvidia/nvidia.Kbuild +++ b/kernel-open/nvidia/nvidia.Kbuild @@ -195,6 +195,7 @@ NV_CONFTEST_FUNCTION_COMPILE_TESTS += get_task_ioprio NV_CONFTEST_FUNCTION_COMPILE_TESTS += mdev_set_iommu_device NV_CONFTEST_FUNCTION_COMPILE_TESTS += offline_and_remove_memory NV_CONFTEST_FUNCTION_COMPILE_TESTS += crypto_tfm_ctx_aligned +NV_CONFTEST_FUNCTION_COMPILE_TESTS += module_import_ns_takes_string_literal NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_of_node_to_nid NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_sme_active @@ -227,8 +228,10 @@ NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_alloc_me NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_tsec_comms_free_gscco_mem NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_memory_block_size_bytes NV_CONFTEST_SYMBOL_COMPILE_TESTS += crypto +NV_CONFTEST_SYMBOL_COMPILE_TESTS += crypto_akcipher_verify NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_present_follow_pte NV_CONFTEST_SYMBOL_COMPILE_TESTS += is_export_symbol_gpl_pci_ats_supported +NV_CONFTEST_SYMBOL_COMPILE_TESTS += ecc_digits_from_bytes NV_CONFTEST_TYPE_COMPILE_TESTS += dma_ops NV_CONFTEST_TYPE_COMPILE_TESTS += swiotlb_dma_ops diff --git a/src/common/inc/nvBldVer.h b/src/common/inc/nvBldVer.h index 977f2f8f5..eca406787 100644 --- a/src/common/inc/nvBldVer.h +++ b/src/common/inc/nvBldVer.h @@ -36,25 +36,25 @@ // and then checked back in. You cannot make changes to these sections without // corresponding changes to the buildmeister script #ifndef NV_BUILD_BRANCH - #define NV_BUILD_BRANCH r550_00 + #define NV_BUILD_BRANCH r553_54 #endif #ifndef NV_PUBLIC_BRANCH - #define NV_PUBLIC_BRANCH r550_00 + #define NV_PUBLIC_BRANCH r553_54 #endif #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) -#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r550/r550_00-505" -#define NV_BUILD_CHANGELIST_NUM (35247928) +#define NV_BUILD_BRANCH_VERSION "rel/gpu_drv/r550/r553_54-516" +#define NV_BUILD_CHANGELIST_NUM (35333542) #define NV_BUILD_TYPE "Official" -#define NV_BUILD_NAME "rel/gpu_drv/r550/r550_00-505" -#define NV_LAST_OFFICIAL_CHANGELIST_NUM (35247928) +#define NV_BUILD_NAME "rel/gpu_drv/r550/r553_54-516" +#define NV_LAST_OFFICIAL_CHANGELIST_NUM (35333542) #else /* Windows builds */ -#define NV_BUILD_BRANCH_VERSION "r550_00-470" -#define NV_BUILD_CHANGELIST_NUM (35247928) +#define NV_BUILD_BRANCH_VERSION "r553_54-2" +#define NV_BUILD_CHANGELIST_NUM (35311700) #define NV_BUILD_TYPE "Official" -#define NV_BUILD_NAME "553.50" -#define NV_LAST_OFFICIAL_CHANGELIST_NUM (35247928) +#define NV_BUILD_NAME "553.56" +#define NV_LAST_OFFICIAL_CHANGELIST_NUM (35311700) #define NV_BUILD_BRANCH_BASE_VERSION R550 #endif // End buildmeister python edited section diff --git a/src/common/inc/nvUnixVersion.h b/src/common/inc/nvUnixVersion.h index be96f3410..6c938344d 100644 --- a/src/common/inc/nvUnixVersion.h +++ b/src/common/inc/nvUnixVersion.h @@ -4,7 +4,7 @@ #if defined(NV_LINUX) || defined(NV_BSD) || defined(NV_SUNOS) || defined(NV_VMWARE) || defined(NV_QNX) || defined(NV_INTEGRITY) || \ (defined(RMCFG_FEATURE_PLATFORM_GSP) && RMCFG_FEATURE_PLATFORM_GSP == 1) -#define NV_VERSION_STRING "550.142" +#define NV_VERSION_STRING "550.144.03" #else diff --git a/src/common/inc/swref/published/ampere/ga100/dev_nv_pcfg_xve_regmap.h b/src/common/inc/swref/published/ampere/ga100/dev_nv_pcfg_xve_regmap.h new file mode 100644 index 000000000..7fc6deef8 --- /dev/null +++ b/src/common/inc/swref/published/ampere/ga100/dev_nv_pcfg_xve_regmap.h @@ -0,0 +1,71 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef __dev_nv_pcfg_xve_regmap_h__ +#define __dev_nv_pcfg_xve_regmap_h__ + +#define NV_PCFG_XVE_REGISTER_MAP_START_OFFSET 0x00088000 + +/* + * _MAP has 1 bit set for each dword register. + * _COUNT has total number of set bits in _MAP. + */ +#define NV_PCFG_XVE_REGISTER_VALID_COUNT 445 +#define NV_PCFG_XVE_REGISTER_VALID_MAP { \ + /* 0x00088000 */ 0xFFF1FFFF, 0x139FFF9F, \ + /* 0x00088100 */ 0x1FBA3C7F, 0x00000000, \ + /* 0x00088200 */ 0x03F00000, 0x00000000, \ + /* 0x00088300 */ 0x00000000, 0x00000000, \ + /* 0x00088400 */ 0x8007FFC0, 0x3F3F5807, \ + /* 0x00088500 */ 0x000000BF, 0x00000000, \ + /* 0x00088600 */ 0x0140AA1F, 0x00000000, \ + /* 0x00088700 */ 0x0001FFFF, 0x00000000, \ + /* 0x00088800 */ 0xFFEFDFD7, 0x1EDAFFFF, \ + /* 0x00088900 */ 0xFFFFFFFF, 0x000FFFFF, \ + /* 0x00088A00 */ 0xFF7FFFFF, 0x0007FFFF, \ + /* 0x00088B00 */ 0x00000000, 0xFFFFF000, \ + /* 0x00088C00 */ 0x0007BFE7, 0xFFFFFFFC, \ + /* 0x00088D00 */ 0xFFFFFFFF, 0x7FFF3FFF, \ + /* 0x00088E00 */ 0x000007FF, 0x00000000, \ + /* 0x00088F00 */ 0x00000000, 0xFC000000 } + +#define NV_PCFG_XVE_REGISTER_WR_COUNT 321 +#define NV_PCFG_XVE_REGISTER_WR_MAP { \ + /* 0x00088000 */ 0x3EF193FA, 0x1187C505, \ + /* 0x00088100 */ 0x1FBA0828, 0x00000000, \ + /* 0x00088200 */ 0x03200000, 0x00000000, \ + /* 0x00088300 */ 0x00000000, 0x00000000, \ + /* 0x00088400 */ 0x80007EC0, 0x3F075007, \ + /* 0x00088500 */ 0x000000BF, 0x00000000, \ + /* 0x00088600 */ 0x0140AA10, 0x00000000, \ + /* 0x00088700 */ 0x0001FFFF, 0x00000000, \ + /* 0x00088800 */ 0x004C5FC3, 0x1C5AFFC0, \ + /* 0x00088900 */ 0xFFFC7804, 0x000FFFFF, \ + /* 0x00088A00 */ 0xFF7FFDFD, 0x00007FFF, \ + /* 0x00088B00 */ 0x00000000, 0xF8A54000, \ + /* 0x00088C00 */ 0x00003C01, 0x3FFFFFFC, \ + /* 0x00088D00 */ 0xFFFFFFFC, 0x739B2C3F, \ + /* 0x00088E00 */ 0x000007F8, 0x00000000, \ + /* 0x00088F00 */ 0x00000000, 0xFC000000 } + +#endif // {__dev_nv_pcfg_xve_regmap_h__} diff --git a/src/common/nvswitch/kernel/ls10/multicast_ls10.c b/src/common/nvswitch/kernel/ls10/multicast_ls10.c index faec64e03..84f9c704a 100644 --- a/src/common/nvswitch/kernel/ls10/multicast_ls10.c +++ b/src/common/nvswitch/kernel/ls10/multicast_ls10.c @@ -209,38 +209,43 @@ _nvswitch_mc_print_directives } #endif // defined(NVSWITCH_MC_TRACE) -// -// Build column-port bitmap. Each 32-bit portmap in the array represents a column. -// Each bit set in the portmap represents the column-relative port offset. -// + +// build column-port array static NvlStatus -_nvswitch_mc_build_cpb +_nvswitch_mc_build_ports_array ( nvswitch_device *device, NvU32 num_ports, NvU32 *spray_group, - NvU32 num_columns, - NvU32 *cpb, + NVSWITCH_COLUMN_PORT_OFFSET_LS10 *ports, NvU8 *vchop_array_sg, NvU8 vchop_map[NVSWITCH_MC_NUM_COLUMNS_LS10][NVSWITCH_MC_PORTS_PER_COLUMN_LS10] ) { + NvU64 ports_used = 0; NvU32 i, ret; NVSWITCH_COLUMN_PORT_OFFSET_LS10 cpo; - - if ((spray_group == NULL) || (cpb == NULL) || (num_ports == 0) || - (num_ports > NVSWITCH_NUM_LINKS_LS10)) + if ((spray_group == NULL) || (ports == NULL) || (num_ports == 0) || + (num_ports > NVSWITCH_MC_TCP_LIST_SIZE_LS10)) { NVSWITCH_PRINT(device, ERROR, "%s: invalid arguments\n", __FUNCTION__); return -NVL_BAD_ARGS; } - nvswitch_os_memset(cpb, 0, sizeof(*cpb) * num_columns); nvswitch_os_memset(vchop_map, 0, sizeof(NvU8) * NVSWITCH_MC_NUM_COLUMNS_LS10 * NVSWITCH_MC_PORTS_PER_COLUMN_LS10); for (i = 0; i < num_ports; i++) { + // prevent duplicate ports + if (ports_used & NVBIT64(spray_group[i])) + { + NVSWITCH_PRINT(device, ERROR, "%s: duplicate port specified: %d\n", __FUNCTION__, + spray_group[i]); + return -NVL_BAD_ARGS; + } + ports_used |= NVBIT64(spray_group[i]); + ret = _nvswitch_get_column_port_offset_ls10(spray_group[i], &cpo); if (ret != NVL_SUCCESS) { @@ -248,14 +253,7 @@ _nvswitch_mc_build_cpb return ret; } - if (nvswitch_test_flags(cpb[cpo.column], NVBIT(cpo.port_offset))) - { - NVSWITCH_PRINT(device, ERROR, "%s: duplicate port specified: %d\n", __FUNCTION__, - spray_group[i]); - return -NVL_BAD_ARGS; - } - - nvswitch_set_flags(&cpb[cpo.column], NVBIT(cpo.port_offset)); + ports[i] = cpo; if (vchop_array_sg[i] > NVSWITCH_MC_VCHOP_FORCE1) { @@ -263,8 +261,6 @@ _nvswitch_mc_build_cpb vchop_array_sg[i]); return -NVL_BAD_ARGS; } - - vchop_map[cpo.column][cpo.port_offset] = vchop_array_sg[i]; } @@ -297,80 +293,6 @@ _is_primary_replica return NV_FALSE; } -// -// This function compacts the directive list and updates port_list_size -// -static NvlStatus -_nvswitch_mc_compact_portlist -( - nvswitch_device *device, - NVSWITCH_TCP_DIRECTIVE_LS10 *port_list, - NvU32 *port_list_size -) -{ - NvU32 cur_portlist_pos, new_portlist_pos; - NVSWITCH_TCP_DIRECTIVE_LS10 *cur_dir, *old_list; - - if (port_list_size == NULL) - { - NVSWITCH_PRINT(device, ERROR, "%s: port list size ptr is null\n", __FUNCTION__); - return -NVL_BAD_ARGS; - } - - if ((port_list == NULL) || (*port_list_size == 0)) - return NVL_SUCCESS; - - if ((*port_list_size) > NVSWITCH_MC_TCP_LIST_SIZE_LS10) - { - NVSWITCH_PRINT(device, ERROR, "%s: port list size out of range\n", __FUNCTION__); - return -NVL_BAD_ARGS; - } - -#ifdef NVSWITCH_MC_DEBUG - NVSWITCH_PRINT(device, INFO, "%s: old size: %d\n", __FUNCTION__, *port_list_size); -#endif - - // create temporary directive list - old_list = nvswitch_os_malloc(sizeof(NVSWITCH_TCP_DIRECTIVE_LS10) * (*port_list_size)); - - if (!old_list) - { - NVSWITCH_PRINT(device, ERROR, "%s: error allocating temporary portlist\n", __FUNCTION__); - return -NVL_NO_MEM; - } - - nvswitch_os_memcpy(old_list, port_list, sizeof(NVSWITCH_TCP_DIRECTIVE_LS10) * (*port_list_size)); - - // rebuild list using only valid entries - new_portlist_pos = 0; - - for (cur_portlist_pos = 0; cur_portlist_pos < (*port_list_size); cur_portlist_pos++) - { - cur_dir = &old_list[cur_portlist_pos]; - - if (cur_dir->tcp != NVSWITCH_MC_INVALID) - { -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: valid directive:\n", __FUNCTION__); - _nvswitch_mc_print_directive(device, &old_list[cur_portlist_pos]); -#endif - nvswitch_os_memcpy(&port_list[new_portlist_pos], &old_list[cur_portlist_pos], - sizeof(NVSWITCH_TCP_DIRECTIVE_LS10)); - new_portlist_pos++; - } - } - - nvswitch_os_free(old_list); - -#ifdef NVSWITCH_MC_DEBUG - NVSWITCH_PRINT(device, INFO, "%s: new size: %d\n", __FUNCTION__, new_portlist_pos); -#endif - - *port_list_size = new_portlist_pos; - - return NVL_SUCCESS; -} - // // Set the round flags to indicate the size of each multicast round. // See IAS section "6.12. Consistent MC Semantics" for more info. @@ -484,118 +406,13 @@ _nvswitch_mc_set_port_flags } } -// -// This function "pops" the next port offset from the portlist bitmap. -// -static NV_INLINE NvU8 -_nvswitch_mc_get_next_port -( - NvU32 *portmap -) -{ - NvU32 port; - - if (!portmap) - { - NVSWITCH_ASSERT(0); - return NVSWITCH_MC_NULL_PORT_LS10; - } - - // - // We have to do some gymnastics here because LOWESTBITIDX_32 is - // destructive on the input variable, and the result is not assignable. - // - port = *portmap; - LOWESTBITIDX_32(port); - nvswitch_clear_flags(portmap, NVBIT(port)); - - if (port >= NVSWITCH_MC_PORTS_PER_COLUMN_LS10) - { - NVSWITCH_ASSERT(0); - return NVSWITCH_MC_NULL_PORT_LS10; - } - - return (NvU8)port; -} - -// -// This helper function generates a map of directive list offsets indexed by tile/column pair -// port offsets. This is used during construction of the directive list to point to where each -// newly constructed directive will be placed in the list. This process has to account for the -// fact that the middle two columns contain 10 ports each, while the rest have 11, all mapping -// into a 32-entry directive list. -// -static NV_INLINE void -_nvswitch_mc_build_mcplist_position_map -( - NvU32 port_offsets_by_tcp[NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10][NVSWITCH_MC_PORTS_PER_COLUMN_LS10] -) -{ - NvU32 i, j, tcp; - - if (!port_offsets_by_tcp) - { - NVSWITCH_ASSERT(0); - return; - } - - for (tcp = 0; tcp < NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10; tcp++) - { - if (tcp == 0) - { - j = 0; - for (i = 0; i < NVSWITCH_MC_PORTS_PER_COLUMN_LS10; i++) - { - port_offsets_by_tcp[tcp][i] = j; - j += NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10; - } - } - - if (tcp == 1) - { - j = 1; - for (i = 0; i < NVSWITCH_MC_PORTS_PER_COLUMN_LS10 - 1; i++) - { - port_offsets_by_tcp[tcp][i] = j; - j += NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10; - } - } - - if (tcp == 2) - { - j = 2; - for (i = 0; i < NVSWITCH_MC_PORTS_PER_COLUMN_LS10; i++) - { - port_offsets_by_tcp[tcp][i] = (j == NVSWITCH_MC_TCP_LIST_SIZE_LS10) ? - (NVSWITCH_MC_TCP_LIST_SIZE_LS10 - 1) : j; - j += NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10; - } - } - } -} - -// -// Wrapper for the NUMSETBITS_32 macro, which is destructive on input. -// -static NV_INLINE NvU32 -_nvswitch_mc_get_pop_count -( - NvU32 i -) -{ - NvU32 tmp = i; - - NUMSETBITS_32(tmp); - - return tmp; -} - // // Build a list of TCP directives. This is the main conversion function which is used to build a // TCP directive list for each spray group from a given column/port bitmap. // // @param device [in] pointer to the nvswitch device struct -// @param cpb [in] pointer to the column/port bitmap used to build directive list +// @param num_ports [in] number of ports +// @param ports [in] ports array (pair of column and port offset) // @param primary_replica [in] the primary replica port for this spray group, if specified // @param vchop_map [in] array containing per-port vchop values in column/port format // @param port_list [out] array where the newly built directive list is written @@ -605,330 +422,66 @@ static NvlStatus _nvswitch_mc_build_portlist ( nvswitch_device *device, - NvU32 *cpb, + NvU32 num_ports, + NVSWITCH_COLUMN_PORT_OFFSET_LS10 *ports, NvU32 primary_replica, NvU8 vchop_map[NVSWITCH_MC_NUM_COLUMNS_LS10][NVSWITCH_MC_PORTS_PER_COLUMN_LS10], NVSWITCH_TCP_DIRECTIVE_LS10 *port_list, NvU32 *entries_used ) { - NvU32 ecol_idx, ocol_idx, ecol_portcount, ocol_portcount, ecol_portmap, ocol_portmap; - NvU32 cur_portlist_pos, j, cur_portlist_slot, last_portlist_pos; - NvU8 cur_eport, cur_oport, i; - NvS32 extra_ports; - NvU32 port_offsets_by_tcp[NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10][NVSWITCH_MC_PORTS_PER_COLUMN_LS10]; + NvU8 last_portlist_pos; + NvU8 i; NVSWITCH_TCP_DIRECTIVE_LS10 *cur_dir; - if ((cpb == NULL) || (port_list == NULL)) + if ((ports == NULL) || (port_list == NULL)) { NVSWITCH_PRINT(device, ERROR, "%s: Invalid arguments\n", __FUNCTION__); return -NVL_BAD_ARGS; } - _nvswitch_mc_build_mcplist_position_map(port_offsets_by_tcp); - - // - // process columns pairwise. if one column is larger than the other by 2 or more entries, - // set the port as alt path - // - - cur_portlist_pos = 0; - last_portlist_pos = 0; - cur_portlist_slot = 0; - - for ( i = 0; i < NVSWITCH_MC_NUM_COLUMN_PAIRS_LS10; i++ ) + // 6.15.2. Route Interface Description + for (i = 0 ; i < num_ports ; ++i) { - ecol_idx = 2 * i; - ocol_idx = 2 * i + 1; - ecol_portmap = cpb[ecol_idx]; - ocol_portmap = cpb[ocol_idx]; + NvU8 cur_port = ports[i].port_offset; + NvU32 cur_col = ports[i].column; - ecol_portcount = _nvswitch_mc_get_pop_count(ecol_portmap); - ocol_portcount = _nvswitch_mc_get_pop_count(ocol_portmap); - - extra_ports = ecol_portcount - ocol_portcount; - - // Start current portlist position on column offset of the current column - cur_portlist_slot = 0; - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - - if ( extra_ports >= 0 ) - { - // - // even column has more ports or both columns have an equal number - // iterate on odd column port count to go through both columns - // - for (j = 0; j < ocol_portcount; j++, cur_portlist_slot++) + // Populating either EVEN or ODD column but not both + cur_dir = &port_list[i]; + cur_dir->primaryReplica = PRIMARY_REPLICA_NONE; + cur_dir->tcp = cur_col/2; // tile-column pair numbering + if (cur_col % 2 == 1) + { // odd column port + cur_dir->tcpOPort = cur_port; + cur_dir->tcpEPort = NVSWITCH_MC_NULL_PORT_LS10; + cur_dir->tcpOVCHop = vchop_map[cur_col][cur_port]; + if (_is_primary_replica(cur_col, cur_port, primary_replica)) { - cur_eport = _nvswitch_mc_get_next_port(&ecol_portmap); - cur_oport = _nvswitch_mc_get_next_port(&ocol_portmap); - if ((cur_eport == NVSWITCH_MC_NULL_PORT_LS10) || - (cur_oport == NVSWITCH_MC_NULL_PORT_LS10)) - { - return -NVL_ERR_GENERIC; - } + cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - // assign the ports to the current directive - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - cur_dir->tcpEPort = cur_eport; - cur_dir->tcpOPort = cur_oport; - - cur_dir->tcpEVCHop = vchop_map[ecol_idx][cur_eport]; - cur_dir->tcpOVCHop = vchop_map[ocol_idx][cur_oport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_eport: %d, cur_oport %d\n", - __FUNCTION__, i, extra_ports, cur_eport, cur_oport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); +#ifdef NVSWITCH_MC_DEBUG + NVSWITCH_PRINT(device, DEBUG, "%s: Odd column primary replica programmed: %d %d\n", + __FUNCTION__, primary_replica, i); #endif - // set primary replica - if (_is_primary_replica(ocol_idx, cur_oport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - - if (_is_primary_replica(ecol_idx, cur_eport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; - - } - - // if both columns had the same number of ports, move on to the next column pair - if (!extra_ports) - { - last_portlist_pos = NV_MAX(last_portlist_pos, cur_portlist_pos); - continue; - } - - // - // otherwise, handle remaining ports in even column - // for the first extra port, assign it directly - // cur_portlist_slot is incremented by the last iteration, or 0 - // - cur_eport = _nvswitch_mc_get_next_port(&ecol_portmap); - if (cur_eport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - cur_dir->tcpEPort = cur_eport; - - cur_dir->tcpEVCHop = vchop_map[ecol_idx][cur_eport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_eport: %d\n", - __FUNCTION__, i, extra_ports, cur_eport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - - // if this is the primary replica port, mark it - if (_is_primary_replica(ecol_idx, cur_eport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; - - extra_ports--; - - // if there are more, assign to altpath - while (extra_ports) - { - // get next port from even column - cur_eport = _nvswitch_mc_get_next_port(&ecol_portmap); - if (cur_eport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - // assign it to odd port in current directive (altpath) - cur_dir->tcpOPort = cur_eport; - cur_dir->tcpOAltPath = NV_TRUE; - - cur_dir->tcpOVCHop = vchop_map[ecol_idx][cur_eport]; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_eport: %d (alt)\n", - __FUNCTION__, i, extra_ports, cur_eport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - // if this is the primary replica port, mark _ODD due to altpath - if (_is_primary_replica(ecol_idx, cur_eport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - - extra_ports--; - - // if there are more ports remaining, start the next entry - if (extra_ports) - { - // advance the portlist entry - cur_portlist_slot++; - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - - cur_eport = _nvswitch_mc_get_next_port(&ecol_portmap); - if (cur_eport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - cur_dir->tcpEPort = cur_eport; - - cur_dir->tcpEVCHop = vchop_map[ecol_idx][cur_eport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_eport: %d\n", - __FUNCTION__, i, extra_ports, cur_eport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - - // if this is the primary replica port, mark it - if (_is_primary_replica(ecol_idx, cur_eport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; - - extra_ports--; - } } } else - { - // odd column has more ports - extra_ports = -extra_ports; - - // iterate over even column to go through port pairs - for (j = 0; j < ecol_portcount; j++, cur_portlist_slot++) + { // even column port + cur_dir->tcpEPort = cur_port; + cur_dir->tcpOPort = NVSWITCH_MC_NULL_PORT_LS10; + cur_dir->tcpEVCHop = vchop_map[cur_col][cur_port]; + if (_is_primary_replica(cur_col, cur_port, primary_replica)) { - cur_eport = _nvswitch_mc_get_next_port(&ecol_portmap); - cur_oport = _nvswitch_mc_get_next_port(&ocol_portmap); - if ((cur_eport == NVSWITCH_MC_NULL_PORT_LS10) || - (cur_oport == NVSWITCH_MC_NULL_PORT_LS10)) - { - return -NVL_ERR_GENERIC; - } - - // assign the ports to the current directive - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - cur_dir->tcpEPort = cur_eport; - cur_dir->tcpOPort = cur_oport; - - cur_dir->tcpEVCHop = vchop_map[ecol_idx][cur_eport]; - cur_dir->tcpOVCHop = vchop_map[ocol_idx][cur_oport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_eport: %d, cur_oport %d\n", - __FUNCTION__, i, extra_ports, cur_eport, cur_oport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); + cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; +#ifdef NVSWITCH_MC_DEBUG + NVSWITCH_PRINT(device, DEBUG, "%s: Even column primary replica programmed: %d %d\n", + __FUNCTION__, primary_replica, i); #endif - if (_is_primary_replica(ocol_idx, cur_oport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - if (_is_primary_replica(ecol_idx, cur_eport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; - - } - - // handle the leftover ports in odd column - cur_oport = _nvswitch_mc_get_next_port(&ocol_portmap); - if (cur_oport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - // cur_portlist_slot is incremented by the last iteration, or 0 - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - - cur_dir->tcpOPort = cur_oport; - - cur_dir->tcpOVCHop = vchop_map[ocol_idx][cur_oport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_oport %d\n", - __FUNCTION__, i, extra_ports, cur_oport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - - if (_is_primary_replica(ocol_idx, cur_oport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - - extra_ports--; - - // process any remaining ports in odd column - while (extra_ports) - { - // get next odd port - cur_oport = _nvswitch_mc_get_next_port(&ocol_portmap); - if (cur_oport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - // set it as even altpath port in current directive - cur_dir->tcpEPort = cur_oport; - cur_dir->tcpEAltPath = NV_TRUE; - - cur_dir->tcpEVCHop = vchop_map[ocol_idx][cur_oport]; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_oport %d (alt)\n", - __FUNCTION__, i, extra_ports, cur_oport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - // if this is the primary replica port, mark _EVEN due to altpath - if (_is_primary_replica(ocol_idx, cur_oport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_EVEN; - - extra_ports--; - - // if there is another port, it goes in the next directive - if (extra_ports) - { - cur_portlist_slot++; - cur_portlist_pos = port_offsets_by_tcp[i][cur_portlist_slot]; - cur_dir = &port_list[cur_portlist_pos]; - - cur_oport = _nvswitch_mc_get_next_port(&ocol_portmap); - if (cur_oport == NVSWITCH_MC_NULL_PORT_LS10) - { - return -NVL_ERR_GENERIC; - } - - cur_dir->tcpOPort = cur_oport; - - cur_dir->tcpOVCHop = vchop_map[ocol_idx][cur_oport]; - - cur_dir->tcp = i; - -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: tcp: %d, extra: %d, cur_oport %d\n", - __FUNCTION__, i, extra_ports, cur_oport); - NVSWITCH_PRINT(device, INFO, "%s: cur_portlist_pos: %d\n", __FUNCTION__, - cur_portlist_pos); -#endif - - if (_is_primary_replica(ocol_idx, cur_oport, primary_replica)) - cur_dir->primaryReplica = PRIMARY_REPLICA_ODD; - - extra_ports--; - } } } - last_portlist_pos = NV_MAX(last_portlist_pos, cur_portlist_pos); + last_portlist_pos = i; } // set the lastRound flag for the last entry in the spray string @@ -939,8 +492,8 @@ _nvswitch_mc_build_portlist #ifdef NVSWITCH_MC_DEBUG NVSWITCH_PRINT(device, INFO, - "%s: entries_used: %d, cur_portlist_pos: %d last_portlist_pos: %d\n", - __FUNCTION__, *entries_used, cur_portlist_pos, last_portlist_pos); + "%s: entries_used: %d, last_portlist_pos: %d\n", + __FUNCTION__, *entries_used, last_portlist_pos); #endif return NVL_SUCCESS; @@ -1068,7 +621,7 @@ nvswitch_mc_build_mcp_list_ls10 NvU32 dir_entries_used_sg = 0; NvU32 dir_entries_used = 0; NvU32 mcplist_offset = 0; - NvU32 cpb[NVSWITCH_MC_NUM_COLUMNS_LS10] = { 0 }; + NVSWITCH_COLUMN_PORT_OFFSET_LS10 ports[NVSWITCH_NUM_LINKS_LS10]; NvU8 vchop_map[NVSWITCH_MC_NUM_COLUMNS_LS10][NVSWITCH_MC_PORTS_PER_COLUMN_LS10]; NVSWITCH_TCP_DIRECTIVE_LS10 tmp_mcp_list[NVSWITCH_MC_TCP_LIST_SIZE_LS10]; NVSWITCH_TCP_DIRECTIVE_LS10 *mcp_list; @@ -1108,7 +661,7 @@ nvswitch_mc_build_mcp_list_ls10 return -NVL_BAD_ARGS; } - if (ports_per_spray_group[i] > NVSWITCH_NUM_LINKS_LS10) + if (ports_per_spray_group[i] > NVSWITCH_MC_TCP_LIST_SIZE_LS10) { NVSWITCH_PRINT(device, ERROR, "%s: Too many ports in spray group %d\n", __FUNCTION__, i); @@ -1118,7 +671,7 @@ nvswitch_mc_build_mcp_list_ls10 j += ports_per_spray_group[i]; } - if (j > NVSWITCH_NUM_LINKS_LS10) + if (j > NVSWITCH_MC_TCP_LIST_SIZE_LS10) { NVSWITCH_PRINT(device, ERROR, "%s: Too many ports specified in total spray groups: %d\n", __FUNCTION__, j); @@ -1143,14 +696,13 @@ nvswitch_mc_build_mcp_list_ls10 if (ret != NVL_SUCCESS) return ret; - ret = _nvswitch_mc_build_cpb(device, spray_group_size, &port_list[spray_group_offset], - NVSWITCH_MC_NUM_COLUMNS_LS10, cpb, - &vchop_array[spray_group_offset], vchop_map); + ret = _nvswitch_mc_build_ports_array(device, spray_group_size, &port_list[spray_group_offset], + ports, &vchop_array[spray_group_offset], vchop_map); if (ret != NVL_SUCCESS) { NVSWITCH_PRINT(device, ERROR, - "%s: error building column-port bitmap for spray group %d: %d\n", + "%s: error building port-column array for spray group %d: %d\n", __FUNCTION__, spray_group_idx, ret); return ret; } @@ -1158,25 +710,6 @@ nvswitch_mc_build_mcp_list_ls10 // Set the offset to this spray group in the mcp list. spray_group_ptrs[spray_group_idx] = (NvU8)dir_entries_used; -#ifdef NVSWITCH_MC_TRACE - NVSWITCH_PRINT(device, INFO, "%s: spray group offset for group %d is %d\n", - __FUNCTION__, spray_group_idx, dir_entries_used); - - for (i = 0; i < NVSWITCH_MC_NUM_COLUMNS_LS10; i++) - { - NVSWITCH_PRINT(device, INFO, "%d Relative ports in column %d\n", - _nvswitch_mc_get_pop_count(cpb[i]), i); - - for ( j = 0; j < 32; j++ ) - { - if (nvswitch_test_flags(cpb[i], NVBIT(j))) - { - NVSWITCH_PRINT(device, INFO, "%4d", j); - } - } - NVSWITCH_PRINT(device, INFO, "\n"); - } -#endif // if primary replica is specified for this spray group, find the port number if (replica_valid_array[spray_group_idx]) { @@ -1220,8 +753,7 @@ nvswitch_mc_build_mcp_list_ls10 NVSWITCH_PRINT(device, INFO, "%s: building tmp mc portlist at mcp offset %d, size %d\n", __FUNCTION__, mcplist_offset, spray_group_size); #endif - - ret = _nvswitch_mc_build_portlist(device, cpb, primary_replica_port, vchop_map, + ret = _nvswitch_mc_build_portlist(device, spray_group_size, ports, primary_replica_port, vchop_map, tmp_mcp_list, &dir_entries_used_sg); if (ret != NVL_SUCCESS) @@ -1234,14 +766,6 @@ nvswitch_mc_build_mcp_list_ls10 NVSWITCH_PRINT(device, INFO, "%s: entries used after building portlist: %d\n", __FUNCTION__, dir_entries_used_sg); #endif - - ret = _nvswitch_mc_compact_portlist(device, tmp_mcp_list, &dir_entries_used_sg); - if (ret != NVL_SUCCESS) - { - NVSWITCH_PRINT(device, ERROR, "%s: error compacting MC portlist\n", __FUNCTION__); - return ret; - } - _nvswitch_mc_set_round_flags(tmp_mcp_list, dir_entries_used_sg); _nvswitch_mc_set_port_flags(tmp_mcp_list, dir_entries_used_sg); @@ -1306,7 +830,7 @@ nvswitch_mc_unwind_directives_ls10 { NvU32 ret = NVL_SUCCESS; NvU32 i, port_idx, cur_sg, ports_in_cur_sg, port, primary_replica; - NVSWITCH_TCP_DIRECTIVE_LS10 cur_dir, prev_dir; + NVSWITCH_TCP_DIRECTIVE_LS10 cur_dir; cur_sg = 0; port_idx = 0; @@ -1344,33 +868,30 @@ nvswitch_mc_unwind_directives_ls10 } // - // If the previous TCP directive's portFlag = 0, and if it was not - // used to select the even or odd port of its predecessor, and this - // directive's portFlag == 1, this TCP directive contains the + // If directive's portFlag == 1, this TCP directive contains the // primary replica, and the next TCP directive's portFlag = 0/1 // selects the even/odd port of this TCP directive. // - - // If we don't have the first or last directive and portFlag == 1 - else if ((i < (NVSWITCH_MC_TCP_LIST_SIZE_LS10 - 1)) && (i > 0) && (cur_dir.portFlag == 1)) + else if ((i < (NVSWITCH_MC_TCP_LIST_SIZE_LS10 - 1)) && (cur_dir.portFlag == 1)) { - prev_dir = directives[i - 1]; - - // Is the previous directive in the same sg and is the portFlag == 0? - if ((prev_dir.lastRound == 0) && (prev_dir.portFlag == 0)) - { - // Check if there is no predecessor, or if the predecessor's portFlag == 0 - if ((i < 2) || (directives[i - 2].portFlag == 0)) - { - // The next directive's portFlags specify even or odd - if (directives[i + 1].portFlag) - primary_replica = PRIMARY_REPLICA_ODD; - else - primary_replica = PRIMARY_REPLICA_EVEN; - } - } + // The next directive's portFlags specify even or odd + if (directives[i + 1].portFlag) + primary_replica = PRIMARY_REPLICA_ODD; + else + primary_replica = PRIMARY_REPLICA_EVEN; } +#ifdef NVSWITCH_MC_TRACE + if (primary_replica == PRIMARY_REPLICA_ODD) { + NVSWITCH_PRINT(device, INFO, "%s: Odd primary replica detected: %d\n", + __FUNCTION__, i); + } + if (primary_replica == PRIMARY_REPLICA_EVEN) { + NVSWITCH_PRINT(device, INFO, "%s: Even primary replica detected: %d\n", + __FUNCTION__, i); + } +#endif + if (cur_dir.tcpEPort != NVSWITCH_MC_NULL_PORT_LS10) { ports_in_cur_sg++; @@ -1510,6 +1031,13 @@ nvswitch_mc_invalidate_mc_rid_entry_ls10 return -NVL_BAD_ARGS; } + if (nvswitch_is_tnvl_mode_locked(device)) + { + NVSWITCH_PRINT(device, ERROR, + "%s(%d): Security locked\n", __FUNCTION__, __LINE__); + return -NVL_ERR_INSUFFICIENT_PERMISSIONS; + } + if (use_extended_table) reg = FLD_SET_DRF(_ROUTE, _RIDTABADDR, _RAM_SEL, _SELECTSEXTMCRIDROUTERAM, 0); else @@ -1608,6 +1136,13 @@ nvswitch_mc_program_mc_rid_entry_ls10 return -NVL_BAD_ARGS; } + if (nvswitch_is_tnvl_mode_locked(device)) + { + NVSWITCH_PRINT(device, ERROR, + "%s(%d): Security locked\n", __FUNCTION__, __LINE__); + return -NVL_ERR_INSUFFICIENT_PERMISSIONS; + } + if (table_entry->use_extended_table) reg = FLD_SET_DRF(_ROUTE, _RIDTABADDR, _RAM_SEL, _SELECTSEXTMCRIDROUTERAM, 0); else @@ -1749,6 +1284,13 @@ nvswitch_mc_read_mc_rid_entry_ls10 return -NVL_BAD_ARGS; } + if (nvswitch_is_tnvl_mode_locked(device)) + { + NVSWITCH_PRINT(device, ERROR, + "%s(%d): Security locked\n", __FUNCTION__, __LINE__); + return -NVL_ERR_INSUFFICIENT_PERMISSIONS; + } + // set the address if (table_entry->use_extended_table) reg = FLD_SET_DRF(_ROUTE, _RIDTABADDR, _RAM_SEL, _SELECTSEXTMCRIDROUTERAM, 0); @@ -1841,4 +1383,3 @@ nvswitch_mc_read_mc_rid_entry_ls10 return NVL_SUCCESS; } - diff --git a/src/nvidia/generated/g_kernel_bif_nvoc.c b/src/nvidia/generated/g_kernel_bif_nvoc.c index 0a6919e1d..d5409238a 100644 --- a/src/nvidia/generated/g_kernel_bif_nvoc.c +++ b/src/nvidia/generated/g_kernel_bif_nvoc.c @@ -538,7 +538,11 @@ static void __nvoc_init_funcTable_KernelBif_1(KernelBif *pThis, RmHalspecOwner * } // Hal function -- kbifInitXveRegMap - if (( ((chipHal_HalVarIdx >> 5) == 1UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x000003e0UL) )) /* ChipHal: TU102 | TU104 | TU106 | TU116 | TU117 */ + if (( ((chipHal_HalVarIdx >> 5) == 1UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x00000400UL) )) /* ChipHal: GA100 */ + { + pThis->__kbifInitXveRegMap__ = &kbifInitXveRegMap_GA100; + } + else if (( ((chipHal_HalVarIdx >> 5) == 1UL) && ((1UL << (chipHal_HalVarIdx & 0x1f)) & 0x000003e0UL) )) /* ChipHal: TU102 | TU104 | TU106 | TU116 | TU117 */ { pThis->__kbifInitXveRegMap__ = &kbifInitXveRegMap_TU102; } diff --git a/src/nvidia/generated/g_kernel_bif_nvoc.h b/src/nvidia/generated/g_kernel_bif_nvoc.h index b47f266cd..1d75724f3 100644 --- a/src/nvidia/generated/g_kernel_bif_nvoc.h +++ b/src/nvidia/generated/g_kernel_bif_nvoc.h @@ -790,6 +790,8 @@ static inline NV_STATUS kbifDoFunctionLevelReset_DISPATCH(struct OBJGPU *pGpu, s NV_STATUS kbifInitXveRegMap_TU102(struct OBJGPU *pGpu, struct KernelBif *pKernelBif, NvU8 arg0); +NV_STATUS kbifInitXveRegMap_GA100(struct OBJGPU *pGpu, struct KernelBif *pKernelBif, NvU8 arg0); + NV_STATUS kbifInitXveRegMap_GA102(struct OBJGPU *pGpu, struct KernelBif *pKernelBif, NvU8 arg0); static inline NV_STATUS kbifInitXveRegMap_DISPATCH(struct OBJGPU *pGpu, struct KernelBif *pKernelBif, NvU8 arg0) { diff --git a/src/nvidia/src/kernel/gpu/bif/arch/ampere/kernel_bif_ga100.c b/src/nvidia/src/kernel/gpu/bif/arch/ampere/kernel_bif_ga100.c index 37b9c0d3b..82b37bcac 100644 --- a/src/nvidia/src/kernel/gpu/bif/arch/ampere/kernel_bif_ga100.c +++ b/src/nvidia/src/kernel/gpu/bif/arch/ampere/kernel_bif_ga100.c @@ -28,9 +28,67 @@ #include "published/ampere/ga100/dev_nv_xve_addendum.h" #include "published/ampere/ga100/dev_nv_xve.h" #include "published/ampere/ga100/dev_boot.h" +#include "published/ampere/ga100/dev_nv_pcfg_xve_regmap.h" +#include "nvmisc.h" /* ------------------------ Public Functions -------------------------------- */ +// XVE register map for PCIe config space +static const NvU32 xveRegMapValid[] = NV_PCFG_XVE_REGISTER_VALID_MAP; +static const NvU32 xveRegMapWrite[] = NV_PCFG_XVE_REGISTER_WR_MAP; + +/* ------------------------ Public Functions -------------------------------- */ + +/*! + * This function setups the xve register map pointers + * + * @param[in] pGpu GPU object pointer + * @param[in] pKernelBif Pointer to KernelBif object + * @param[in] func PCIe function number + * + * @return 'NV_OK' if successful, an RM error code otherwise. + */ +NV_STATUS +kbifInitXveRegMap_GA100 +( + OBJGPU *pGpu, + KernelBif *pKernelBif, + NvU8 func +) +{ + extern NvU32 kbifInitXveRegMap_GM107(OBJGPU *pGpu, KernelBif *pKernelBif, NvU8 func); + NV_STATUS status = NV_OK; + NvU32 controlSize = 0; + + if (func == 0) + { + pKernelBif->xveRegmapRef[0].nFunc = 0; + pKernelBif->xveRegmapRef[0].xveRegMapValid = xveRegMapValid; + pKernelBif->xveRegmapRef[0].xveRegMapWrite = xveRegMapWrite; + pKernelBif->xveRegmapRef[0].numXveRegMapValid = NV_ARRAY_ELEMENTS(xveRegMapValid); + pKernelBif->xveRegmapRef[0].numXveRegMapWrite = NV_ARRAY_ELEMENTS(xveRegMapWrite); + pKernelBif->xveRegmapRef[0].bufBootConfigSpace = pKernelBif->cacheData.gpuBootConfigSpace; + // Each MSIX table entry is 4 NvU32s + controlSize = kbifGetMSIXTableVectorControlSize_HAL(pGpu, pKernelBif); + if (pKernelBif->xveRegmapRef[0].bufMsixTable == NULL) + pKernelBif->xveRegmapRef[0].bufMsixTable = portMemAllocNonPaged(controlSize * 4 * sizeof(NvU32)); + NV_ASSERT_OR_RETURN(pKernelBif->xveRegmapRef[0].bufMsixTable != NULL, NV_ERR_NO_MEMORY); + } + else if (func == 1) + { + // Init regmap for Fn1 using older HAL + status = kbifInitXveRegMap_GM107(pGpu, pKernelBif, 1); + } + else + { + NV_PRINTF(LEVEL_ERROR, "Invalid argument, func: %d.\n", func); + NV_ASSERT(0); + status = NV_ERR_INVALID_ARGUMENT; + } + + return status; +} + /*! * @brief Apply WAR for bug 3208922 - disable P2P on Ampere NB * diff --git a/src/nvidia/src/kernel/gpu/fifo/kernel_fifo.c b/src/nvidia/src/kernel/gpu/fifo/kernel_fifo.c index d1766b23c..8687cb44f 100644 --- a/src/nvidia/src/kernel/gpu/fifo/kernel_fifo.c +++ b/src/nvidia/src/kernel/gpu/fifo/kernel_fifo.c @@ -941,13 +941,26 @@ kfifoChidMgrReleaseChid_IMPL if (IS_GFID_VF(gfid)) { - NV_ASSERT_OR_RETURN(pChidMgr->ppVirtualChIDHeap[gfid] != NULL, NV_ERR_INVALID_STATE); - NV_ASSERT_OK(pChidMgr->ppVirtualChIDHeap[gfid]->eheapFree(pChidMgr->ppVirtualChIDHeap[gfid], ChID)); + // + // ppVirtualChIDHeap is freed during hostvgpudeviceapiDestruct in GSP-RM. + // In the case of a GSP-Plugin crash after running the VF doorbell fuzzer, only the hostvgpudeviceapi object is freed in GSP-RM. + // Other resources are cleaned up when shutting down the VM. + // + if (pChidMgr->ppVirtualChIDHeap[gfid] != NULL) + { + NV_ASSERT_OK(pChidMgr->ppVirtualChIDHeap[gfid]->eheapFree(pChidMgr->ppVirtualChIDHeap[gfid], ChID)); + } } else { - NV_ASSERT_OR_RETURN(pChidMgr->pGlobalChIDHeap != NULL, NV_ERR_INVALID_STATE); - NV_ASSERT_OK(pChidMgr->pGlobalChIDHeap->eheapFree(pChidMgr->pGlobalChIDHeap, ChID)); + if (pChidMgr->pGlobalChIDHeap != NULL) + { + NV_ASSERT_OK(pChidMgr->pGlobalChIDHeap->eheapFree(pChidMgr->pGlobalChIDHeap, ChID)); + } + else + { + NV_ASSERT(pChidMgr->pGlobalChIDHeap != NULL); + } } NV_ASSERT_OR_RETURN(pChidMgr->pFifoDataHeap != NULL, NV_ERR_INVALID_STATE); @@ -2691,7 +2704,7 @@ kfifoRunlistAllocBuffers_IMPL } } - memdescTagAlloc(status, NV_FB_ALLOC_RM_INTERNAL_OWNER_UNNAMED_TAG_101, + memdescTagAlloc(status, NV_FB_ALLOC_RM_INTERNAL_OWNER_UNNAMED_TAG_101, ppMemDesc[counter]); if (status != NV_OK) { diff --git a/src/nvidia/src/libraries/nvport/string/string_generic.c b/src/nvidia/src/libraries/nvport/string/string_generic.c index eee9f5ce1..7eb573dec 100644 --- a/src/nvidia/src/libraries/nvport/string/string_generic.c +++ b/src/nvidia/src/libraries/nvport/string/string_generic.c @@ -76,18 +76,34 @@ portStringCompare NvLength maxLength ) { - NvLength length; + NvLength i; PORT_ASSERT_CHECKED(str1 != NULL); PORT_ASSERT_CHECKED(str2 != NULL); - length = portStringLengthSafe(str1, maxLength); + for (i = 0; i < maxLength; i++) + { + if (str1[i] != str2[i]) + { + // + // Cast to unsigned before assigning to NvS32, to avoid sign + // extension. E.g., if str1[i] is 0xff, we want s1 to contain + // 0xff, not -1. In practice, this shouldn't matter for printable + // characters, but still... + // + NvS32 s1 = (unsigned char)str1[i]; + NvS32 s2 = (unsigned char)str2[i]; + return s1 - s2; + } - // Add 1 for the null terminator. - if (length < maxLength) - length++; + if ((str1[i] == '\0') && + (str2[i] == '\0')) + { + break; + } + } - return portMemCmp(str1, str2, length); + return 0; } #endif diff --git a/version.mk b/version.mk index e17e3e51c..44bad3f8d 100644 --- a/version.mk +++ b/version.mk @@ -1,4 +1,4 @@ -NVIDIA_VERSION = 550.142 +NVIDIA_VERSION = 550.144.03 # This file. VERSION_MK_FILE := $(lastword $(MAKEFILE_LIST))