From 535f8ec1f0adb240fe2717375cc91d29c2cf3365 Mon Sep 17 00:00:00 2001 From: lean Date: Wed, 20 Apr 2022 15:32:30 +0800 Subject: [PATCH] =?UTF-8?q?x64:=20add=20Intel=C2=AE=20QuickAssist=20Techno?= =?UTF-8?q?logy=20openssl=20crypto=20hardware=20accel=20suuport=20(C2558?= =?UTF-8?q?=20and=20C3558=20SOC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qat/firmware/quickassist-c2xxx/Config.in | 9 + .../qat/firmware/quickassist-c2xxx/Makefile | 160 + .../files/c2xxx_qa_dev0_single_ae.conf | 175 + .../firmware/quickassist-c2xxx/files/qat.init | 140 + .../quickassist-c2xxx/files/qat_watchdog.init | 119 + .../patches/0001-intel-kernel-v3-to-v4.patch | 360 + .../0002-contig-mem-driver-backport.patch | 5908 +++++++++++++++++ .../qat/firmware/quickassist-c3xxx/Config.in | 104 + .../firmware/quickassist-c3xxx/Config.kernel | 97 + .../qat/firmware/quickassist-c3xxx/Makefile | 236 + .../quickassist-c3xxx/files/c3xxx_dev0.conf | 121 + .../files/c3xxx_dev0.conf.multi | 127 + .../files/hotplug.d/module/01-usdm | 32 + .../hotplug.d/qat_adf_ctl/01-qat_adf_ctl | 8 + .../qat_dev_processes/01-qat_dev_processes | 8 + .../files/hotplug.d/uio/01-uio | 7 + .../files/hotplug.d/usdm_drv/01-usdm | 8 + .../firmware/quickassist-c3xxx/files/qat.init | 175 + .../files/sysctl.d/12-hugepages.conf | 5 + ...ost-dependent-stack-protection-check.patch | 15 + .../0002-remove-host-include-paths.patch | 14 + .../0003-OsalServices-musl-bits-time.patch | 13 + .../patches/0004-musl-PAGE_SIZE.patch | 14 + .../kernel/kmod-crypto-crc32-pclmul/Makefile | 49 + .../kernel/kmod-crypto-crc32c-intel/Makefile | 48 + .../kmod-crypto-crct10dif-pclmu/Makefile | 47 + .../kernel/kmod-crypto-ghash-clmulni/Makefile | 46 + .../kernel/kmod-crypto-misc-cxxxx/Makefile | 63 + .../qat/kernel/kmod-crypto-sha-cxxxx/Makefile | 66 + package/qat/libs/eudev/Config.in | 69 + package/qat/libs/eudev/Makefile | 88 + .../0001-mtd_probe-uses-stdint_h.patch | 12 + .../eudev/patches/0002-udevadm-cutdown.patch | 18 + package/qat/libs/openssl-qat/Config.in | 160 + package/qat/libs/openssl-qat/Makefile | 84 + .../patches/0001-remove-FORTIFY_SOURCE.patch | 21 + .../0002-fix-autoconf-glibc-detection.patch | 27 + .../patches/0003-fix-install-command.patch | 11 + .../patches/0004-usdm_drv-qat16.patch | 11 + .../patches/0005-musl-GLIBC_PREREQ.patch | 15 + package/qat/libs/qatzip/Makefile | 108 + .../qatzip/patches/0001-musl-bits-types.patch | 14 + .../patches/0002-musl-reopen-stdout.patch | 14 + 43 files changed, 8826 insertions(+) create mode 100644 package/qat/firmware/quickassist-c2xxx/Config.in create mode 100644 package/qat/firmware/quickassist-c2xxx/Makefile create mode 100644 package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf create mode 100755 package/qat/firmware/quickassist-c2xxx/files/qat.init create mode 100755 package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init create mode 100644 package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch create mode 100644 package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch create mode 100644 package/qat/firmware/quickassist-c3xxx/Config.in create mode 100644 package/qat/firmware/quickassist-c3xxx/Config.kernel create mode 100644 package/qat/firmware/quickassist-c3xxx/Makefile create mode 100644 package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf create mode 100644 package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi create mode 100755 package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm create mode 100644 package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl create mode 100644 package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes create mode 100644 package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio create mode 100644 package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm create mode 100755 package/qat/firmware/quickassist-c3xxx/files/qat.init create mode 100644 package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf create mode 100644 package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch create mode 100644 package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch create mode 100644 package/qat/firmware/quickassist-c3xxx/patches/0003-OsalServices-musl-bits-time.patch create mode 100644 package/qat/firmware/quickassist-c3xxx/patches/0004-musl-PAGE_SIZE.patch create mode 100644 package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile create mode 100644 package/qat/kernel/kmod-crypto-crc32c-intel/Makefile create mode 100644 package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile create mode 100644 package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile create mode 100644 package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile create mode 100644 package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile create mode 100644 package/qat/libs/eudev/Config.in create mode 100644 package/qat/libs/eudev/Makefile create mode 100644 package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch create mode 100644 package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch create mode 100644 package/qat/libs/openssl-qat/Config.in create mode 100644 package/qat/libs/openssl-qat/Makefile create mode 100644 package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch create mode 100644 package/qat/libs/openssl-qat/patches/0002-fix-autoconf-glibc-detection.patch create mode 100644 package/qat/libs/openssl-qat/patches/0003-fix-install-command.patch create mode 100644 package/qat/libs/openssl-qat/patches/0004-usdm_drv-qat16.patch create mode 100644 package/qat/libs/openssl-qat/patches/0005-musl-GLIBC_PREREQ.patch create mode 100644 package/qat/libs/qatzip/Makefile create mode 100644 package/qat/libs/qatzip/patches/0001-musl-bits-types.patch create mode 100644 package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch diff --git a/package/qat/firmware/quickassist-c2xxx/Config.in b/package/qat/firmware/quickassist-c2xxx/Config.in new file mode 100644 index 000000000..38dfae350 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/Config.in @@ -0,0 +1,9 @@ +menu "Configuration" + depends on PACKAGE_kmod-crypto-qat-c2xxx + +config CRYPTO_QAT_DEBUG + bool + default n + prompt "Build with debugging support enabled" + +endmenu diff --git a/package/qat/firmware/quickassist-c2xxx/Makefile b/package/qat/firmware/quickassist-c2xxx/Makefile new file mode 100644 index 000000000..2cb1ec3b7 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/Makefile @@ -0,0 +1,160 @@ +# +# Copyright (C) DL +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=quickassist-c2xxx + +PKG_VERSION:=1.5 +PKG_RELEASE:=2 + +PKG_SOURCE_VERSION:=1.5.l.1.13.0-19 +PKG_SOURCE:=qat$(PKG_SOURCE_VERSION).tar.gz +PKG_SOURCE_URL:=https://01.org/sites/default/files/downloads/intel-quickassist-technology/ +PKG_HASH:=afe8339edbbf05099e79c256191584aabf30b564f89a553b9585b2f8e18bee17 + +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_BUILD_PARALLEL:=0 + +define Package/quickassist-c2xxx + SECTION:=firmware + CATEGORY:=Firmware + TITLE:=Intel Quick Assist meta-package for c2xxx + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 \ + +libopenssl \ + +kmod-crypto-qat-c2xxx \ + +kmod-crypto-qat-c2xxx-usdm +endef + +define Package/quickassist-c2xxx/config + depends on !quickassist-c3xxx-enabled + config quickassist-c2xxx-enabled + bool + default y if PACKAGE_quickassist-c2xxx + default n +endef + +define Package/quickassist-c2xxx/description + Intel Quick Assist v1.5 utilities and firmware for c2xxx series SoCs +endef + +# +# QAT 1.5 kernel driver +# + +define KernelPackage/crypto-qat-c2xxx + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Technology Drivers + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 \ + +libc \ + +libpthread \ + +libopenssl \ + +kmod-crypto-manager \ + +kmod-crypto-cbc \ + +kmod-crypto-sha1 \ + +kmod-crypto-sha256 \ + +kmod-crypto-sha512 + FILES:=$(PKG_BUILD_DIR)/build/icp_qa_al.ko +endef + +define KernelPackage/crypto-qat-c2xxx/description + Kernel driver for Intel Quick Assist Technology c2xxx +endef + +define KernelPackage/crypto-qat-c2xxx/config + depends on quickassist-c2xxx-enabled + source "$(SOURCE)/Config.in" +endef + +# +# QAT 1.7 contiguous pinned memory driver +# + +define KernelPackage/crypto-qat-c2xxx-usdm + SUBMENU:=Cryptographic API modules + TITLE:=Quick Assist Pinned Memory Driver + DEPENDS:= \ + @TARGET_x86_64 \ + @LINUX_4_14 + FILES:=$(PKG_BUILD_DIR)/build/usdm_drv.ko + AUTOLOAD:=$(call AutoProbe,usdm_drv) +endef + +define KernelPackage/crypto-qat-c2xxx-usdm/config + depends on quickassist-c2xxx-enabled +endef + +define KernelPackage/crypto-qat-c2xxx-usdm/description + Contiguous pinned memory driver for Intel Quick Assist Technology +endef + +ICP_ARCH = x86_64 +MAKE_PATH = quickassist +MAKE_FLAGS = ARCH_USER="$(ICP_ARCH)" + +MAKE_VARS += ICP_ROOT="$(PKG_BUILD_DIR)" \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + MACHINE="$(ICP_ARCH)" \ + ICP_BUILD_OUTPUT="$(PKG_BUILD_DIR)/build" \ + ICP_ENV_DIR="$(PKG_BUILD_DIR)/quickassist/build_system/build_files/env_files" \ + ICP_BUILDSYSTEM_PATH="$(PKG_BUILD_DIR)/quickassist/build_system" \ + ICP_TOOLS_TARGET="accelcomp" \ + ICP_NONBLOCKING_PARTIALS_PERFORM="1" \ + ICP_ARCH_USER="$(ICP_ARCH)" \ + LIB_SHARED_FLAGS="-L$(STAGING_DIR)/usr/lib" \ + LD_LIBRARY_PATH="$(PKG_BUILD_DIR)/build" + +define Build/Prepare + (mkdir -p '$(PKG_BUILD_DIR)' && zcat '$(DL_DIR)/$(PKG_SOURCE)' | tar -C '$(PKG_BUILD_DIR)' -xf -) + $(Build/Patch) +endef + +define Build/Compile + $(call Build/Compile/Default) + $(call Build/Compile/Default, -C $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/src/sample_code perf_all) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/icp/quickassist + $(INSTALL_DIR) $(1)/usr/icp/build + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/include/{*.h,dc,lac} $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/include/*.h $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist $(1)/usr/icp + $(CP) $(PKG_BUILD_DIR)/build $(1)/usr/icp +endef + +define Package/quickassist/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT1.5/config + $(CP) $(PKG_BUILD_DIR)/quickassist/config/* $(1)/usr/share/quickassist/QAT1.5/config + $(CP) $(PKG_BUILD_DIR)/build/adf_ctl $(1)/usr/sbin/adf_ctl + $(CP) $(PKG_BUILD_DIR)/quickassist/adf/build/linux_2.6/icp_gige_watchdog $(1)/usr/sbin/icp_gige_watchdog + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/lib/ + $(CP) $(PKG_BUILD_DIR)/build/*.bin $(1)/lib/firmware/ + $(CP) ./files/qat.init $(1)/etc/init.d/qat + $(CP) ./files/qat_watchdog.init $(1)/etc/init.d/qat_watchdog + $(CP) ./files/c2xxx_qa_dev0_single_ae.conf $(1)/etc/c2xxx_qa_dev0.conf +endef + +$(eval $(call BuildPackage,quickassist-c2xxx)) +$(eval $(call KernelPackage,crypto-qat-c2xxx)) +$(eval $(call KernelPackage,crypto-qat-c2xxx-usdm)) diff --git a/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf b/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf new file mode 100644 index 000000000..3b0acd6b9 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/c2xxx_qa_dev0_single_ae.conf @@ -0,0 +1,175 @@ +######################################################################### +# +# @par +# # This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +######################################################################### + +######################################################## +# General Section +############################################## + +[GENERAL] +ServicesEnabled = cy0 + +# Use version 2 of the config file +ConfigVersion = 2 + +# Look Aside Cryptographic Configuration +cyHmacAuthMode = 1 + +# Firmware Location Configuration +Firmware_MofPath = mof_firmware_c2xxx.bin +Firmware_MmpPath = mmp_firmware_c2xxx.bin + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +#Debug feature, if set to 1 it enables additional entries in /proc filesystem +ProcDebug = 1 + + +####################################################### +# Wireless Section +####################################################### +[WIRELESS] +NumProcesses = 0 + +####################################################### +# +# Logical Instances Section +# A logical instance allows each address domain +# (kernel space and individual user space processes) +# to configure rings (i.e. hardware assisted queues) +# to be used by that address domain and to define the +# behavior of that ring. +# +# The address domains are in the following format +# - For kernel address domains +# [KERNEL] +# - For user process address domains +# [xxxxx] +# Where xxxxx may be any ascii value which uniquely identifies +# the user mode process. +# To allow the driver correctly configure the +# logical instances associated with this user process, +# the process must call the icp_sal_userStart(...) +# passing the xxxxx string during process initialisation. +# When the user space process is finish it must call +# icp_sal_userStop(...) to free resources. +# NumProcesses will indicate the maximum number of processes +# that can call icp_sal_userStart on this instance. +# Warning: the ressources are preallocated: if NumProcesses +# is too high, the driver will fail to load +# +# Items configurable by a logical instance are: +# - Name of the logical instance +# - The accelerator associated with this logical +# instance +# - The core the instance is affinitized to (optional) +# +# Note: Logical instances may not share the same ring, but +# may share a ring bank. +# +# The format of the logical instances are: +# - For crypto: +# CyName = "xxxx" +# CyAcceleratorNumber = 0-1 +# CyCoreAffinity = 0-7 +# +# Note: for user space processes, a list of values can be specified for +# the core affinity: for example +# Cy0CoreAffinity = 0,2,4 +# +# Where: +# - n is the number of this logical instance starting at 0. +# - xxxx may be any ascii value which identifies the logical instance. +# +######################################################## + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 + +############################################## +# Compression multi thread/process section +############################################## +[SHIM] +NumberCyInstances = 1 +NumProcesses = 8 +LimitDevAccess = 1 + +# Crypto - User space +Cy0Name = "UserCY0" +Cy0AcceleratorNumber = 0 +Cy0IsPolled = 1 +Cy0CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c2xxx/files/qat.init b/package/qat/firmware/quickassist-c2xxx/files/qat.init new file mode 100755 index 000000000..cf737bfbf --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/qat.init @@ -0,0 +1,140 @@ +#!/bin/sh /etc/rc.common + +# Adapted from Intel QAT1.5 qat_service. Portions copyright Intel Corporation + +################################################################# +# +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT1.5.L.1.10.0-80 +# +################################################################# + +# qat Start/Stop the Intel QAT. +# +# description: modprobe the QAT icp_qa_al.ko, which loads dependant \ +# modules, before calling the user space \ +# utility to pass configuration parameters + +START=29 +STOP=99 + +PROG=/usr/sbin/adf_ctl +KMOD=icp_qa_al +NETKEY=icp_qat_netkey.ko + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + +status() { + + ${PROG} status + if [ "$?" -ne 0 ] + then + echo "No devices found. Please start the driver using:" + echo "$0 start" + fi + +} + +start() { + + # First check if the modules are already installed + # install them as necessary and if they are LKMs + # and not built-in kernel modules + + if [ `lsmod | grep -c "sha512"` == 0 ]; then + if [ `cat /proc/kallsyms |grep -c sha512_generic` == 0 ]; then + `modprobe sha512` + fi + fi + + if [ `lsmod | grep -c "sha256"` == 0 ]; then + if [ `cat /proc/kallsyms |grep -c sha256_generic` == 0 ]; then + `modprobe sha256` + fi + fi + + lsmod | grep ${KMOD} >/dev/null 2>&1 || modprobe ${KMOD} + + # Check device status, try to turn it on only if driver is loaded + + ${PROG} $2 status | grep state=down >/dev/null 2>&1 + if [ $? = 0 ]; then + ${PROG} $2 up + fi + + # lsmod | grep ${NETKEY} >/dev/null 2>&1 || modprobe ${NETKEY} 2> /dev/null + + # Show device status + + ${PROG} $2 status +} + +stop() { + + ${PROG} $2 down + +} + +restart() { + + ${PROG} $2 down && ${PROG} $2 up + +} + diff --git a/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init b/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init new file mode 100755 index 000000000..24411f992 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/files/qat_watchdog.init @@ -0,0 +1,119 @@ +#!/bin/bash /etc/rc.common + +################################################################# +# +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2013 Intel Corporation. All rights reserved. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +# version: QAT1.5.L.1.10.0-80 +# +################################################################# + + + +START=99 +STOP=99 + +PROG=/usr/sbin/icp_gige_watchdog +PID="`ps | grep ${PROG} | grep -v grep | awk '{print $1}'`" + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + +status() { + + if [ -z "$PID" ] + then + echo "${PROG} not running" + else + echo "${PROG} running: ${PID}" + fi + +} + +start() { + + if [ -z "$PID" ] + then + ${PROG} & + else + echo "Already running pid: ${PID}" + fi + +} + +stop() { + + if [ -z "$PID" ] + then + echo "${PROG} not running" + else + kill -USR1 ${PID} + fi + +} + +restart() { + + stop + start + +} + + + + diff --git a/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch b/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch new file mode 100644 index 000000000..b6a2e5419 --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/patches/0001-intel-kernel-v3-to-v4.patch @@ -0,0 +1,360 @@ +--- a/quickassist/adf/accel_mgr/src/adf_cfg.c ++++ b/quickassist/adf/accel_mgr/src/adf_cfg.c +@@ -545,9 +545,10 @@ CpaStatus adf_cfgAddKeyValueParam(icp_ac + } + else if(ADF_HEX == type) + { +- value_addr = (Cpa64U *)val; +- snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES, +- "0x%p", value_addr); ++// value_addr = (Cpa64U *)val; ++// snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ++// "0x%p", value_addr); ++ snprintf(pKeyValue->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,"0x%lx", (uintptr_t)val); + } + else + { +--- a/quickassist/adf/accelengine/src/adf_ae.c ++++ b/quickassist/adf/accelengine/src/adf_ae.c +@@ -222,6 +222,7 @@ CpaStatus adf_aeFwLoad(icp_accel_dev_t * + /* Get the UoF FW and Map the memory to the AEs */ + status = adf_aefwGetFirmware(pAccelDev, ADF_FW_UOF_TYPE, &addr, &size); + ICP_CHECK_STATUS(status); ++ + /* load ucode for patching, ucode_map */ + status = adf_aeUcodeMap(pAccelDev, addr, size); + if (CPA_STATUS_SUCCESS != status) +--- a/quickassist/adf/accelengine/src/adf_ae_fw.c ++++ b/quickassist/adf/accelengine/src/adf_ae_fw.c +@@ -147,7 +147,6 @@ CpaStatus adf_aefwLoadFirmware(icp_accel + return CPA_STATUS_FAIL; + } + ICP_MEMCPY(pUofFwAddr, pFwAddr, fwSize); +- + /* + * Add the local copies to the config table. + * When the memory address is needed again it can be queried from +@@ -356,14 +355,13 @@ CpaStatus adf_aefwGetFirmware(icp_accel_ + status_addr = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_UOF_ADDRESS_KEY, config_value); + *pAddr = (void *)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_HEX); +- status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, ++ status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_UOF_SIZE_BYTES_KEY, config_value); + *pSize = (Cpa32U)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_DEC); + break; + case ADF_FW_MMP_TYPE: + status_addr = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_MMP_ADDRESS_KEY, config_value); +- *pAddr = (void *)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_HEX); + status_size = icp_adf_cfgGetParamValue(pAccelDev, INTERNAL_SEC, + ICP_CFG_MMP_SIZE_BYTES_KEY, config_value); + *pSize = (Cpa32U)ICP_STRTOUL(config_value, NULL, ADF_CFG_BASE_DEC); +--- a/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_drv.c ++++ b/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_drv.c +@@ -911,7 +911,7 @@ int adf_restore_dev(icp_accel_dev_t *acc + ADF_ERROR("Can not issue secondary bus reset\n"); + ADF_ERROR("Trying FLR\n"); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31) +- ret = __pci_reset_function(pdev); ++ ret = pci_reset_function(pdev); + if (ret) { + ADF_ERROR("Could not reset device\n"); + return ret; +--- a/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_isr.c ++++ b/quickassist/adf/drivers/ACCELDEV/linux/src/adf_acceldev_isr.c +@@ -214,7 +214,7 @@ STATIC int adf_enable_msix(icp_accel_dev + (hw_data->msix.aeVectorStart - hw_data->msix.banksVectorNum); + } + +- stat = pci_enable_msix(pci_dev_info->pDev, ++ stat = pci_enable_msix_exact(pci_dev_info->pDev, + pci_dev_info->msixEntries.value, + msix_num_entries); + if (SUCCESS != stat){ +--- a/quickassist/adf/drivers/common/linux/src/adf_dev_csr.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_dev_csr.c +@@ -80,6 +80,7 @@ + #include "adf_dev_csr.h" + #include "adf_platform.h" + #include ++#include + + #define ADF_DEV_CSR_NAME ("icp_dev_csr") + #define ADF_DEV_CSR_MAX_MINOR (255) +--- a/quickassist/adf/drivers/common/linux/src/adf_dev_ring.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_dev_ring.c +@@ -87,6 +87,7 @@ + #include "icp_adf_init.h" + #include "icp_adf_cfg.h" + #include "adf_proc_debug.h" ++#include + + #define ADF_DEV_RING_NAME ("icp_dev_ring") + #define ADF_DEV_RING_MAX_MINOR (255) +--- a/quickassist/adf/drivers/common/linux/src/adf_gige_wd_drv.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_gige_wd_drv.c +@@ -76,6 +76,8 @@ + #include "adf_platform.h" + #include + #include ++#include ++ + /* Character Device Driver Name */ + #define DEVICE_NAME "icp_adf_gige_wd" + #define COMPLETION_TIME 5000 +--- a/quickassist/adf/drivers/common/linux/src/adf_proc_debug.c ++++ b/quickassist/adf/drivers/common/linux/src/adf_proc_debug.c +@@ -132,17 +132,13 @@ static int adf_debug_show(struct seq_fil + { + debug_file_info_t* file_info = sfile->private; + if (file_info && file_info->seq_read && file_info->page) { +- int ret = 0, old_offset = file_info->offset; +- file_info->offset = +- file_info->seq_read(file_info->private_data, +- file_info->page, PAGE_SIZE - 1, +- file_info->offset); +- ret = seq_puts(sfile, (char*)file_info->page); +- if (ret) { +- /* run out of space - need to reprint */ +- file_info->offset = old_offset; +- } ++ file_info->offset = ++ file_info->seq_read(file_info->private_data, ++ file_info->page, PAGE_SIZE - 1, ++ file_info->offset); ++ seq_puts(sfile, (char*)file_info->page); + } ++ + return 0; + } + +--- a/quickassist/adf/include/icp_adf_transport_dp.h ++++ b/quickassist/adf/include/icp_adf_transport_dp.h +@@ -79,7 +79,7 @@ + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space. + */ +-inline void icp_adf_getQueueMemory(icp_comms_trans_handle trans_handle, ++void icp_adf_getQueueMemory(icp_comms_trans_handle trans_handle, + Cpa32U numberRequests, + void** pCurrentQatMsg); + /* +@@ -87,7 +87,7 @@ inline void icp_adf_getQueueMemory(icp_c + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space - it also updates the shadow tail copy. + */ +-inline void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_handle, ++void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_handle, + void** pCurrentQatMsg); + + /* +@@ -95,26 +95,26 @@ inline void icp_adf_getSingleQueueAddr(i + * Data plain support function - increments the tail pointer and returns + * the pointer to next message on the ring. + */ +-inline void icp_adf_getQueueNext(icp_comms_trans_handle trans_handle, ++void icp_adf_getQueueNext(icp_comms_trans_handle trans_handle, + void** pCurrentQatMsg); + + /* + * icp_adf_updateQueueTail + * Data plain support function - Writes the tail shadow copy to the device. + */ +-inline void icp_adf_updateQueueTail(icp_comms_trans_handle trans_handle); ++void icp_adf_updateQueueTail(icp_comms_trans_handle trans_handle); + + /* + * icp_adf_isRingEmpty + * Data plain support function - check if the ring is empty + */ +-inline CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_handle); ++CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_handle); + + /* + * icp_adf_pollQueue + * Data plain support function - Poll messages from the queue. + */ +-inline CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_handle, ++CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_handle, + Cpa32U response_quota); + + /* +@@ -123,6 +123,6 @@ inline CpaStatus icp_adf_pollQueue(icp_c + * send. This should only be called on request rings. If the function returns + * true then it is ok to call icp_adf_updateQueueTail() function on this ring. + */ +-inline CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd); ++CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd); + + #endif /* ICP_ADF_TRANSPORT_DP_H */ +--- a/quickassist/adf/include/icp_platform_linux.h ++++ b/quickassist/adf/include/icp_platform_linux.h +@@ -90,7 +90,7 @@ + + #include + #include +-#include ++#include + + #include "Osal.h" + +--- a/quickassist/adf/user/user_proxy/src/adf_user_ETring_mgr_dp.c ++++ b/quickassist/adf/user/user_proxy/src/adf_user_ETring_mgr_dp.c +@@ -84,7 +84,7 @@ + * Data plain support function - returns the pointer to next message on the ring + * or NULL if there is not enough space. + */ +-inline void icp_adf_getQueueMemory(icp_comms_trans_handle trans_hnd, ++void icp_adf_getQueueMemory(icp_comms_trans_handle trans_hnd, + Cpa32U numberRequests, + void** pCurrentQatMsg) + { +@@ -114,7 +114,7 @@ inline void icp_adf_getQueueMemory(icp_c + * Data plane support function - returns the pointer to next message on the ring + * or NULL if there is not enough space - it also updates the shadow tail copy. + */ +-inline void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_hnd, ++void icp_adf_getSingleQueueAddr(icp_comms_trans_handle trans_hnd, + void** pCurrentQatMsg) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -147,7 +147,7 @@ inline void icp_adf_getSingleQueueAddr(i + * Data plain support function - increments the tail pointer and returns + * the pointer to next message on the ring. + */ +-inline void icp_adf_getQueueNext(icp_comms_trans_handle trans_hnd, ++void icp_adf_getQueueNext(icp_comms_trans_handle trans_hnd, + void** pCurrentQatMsg) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -168,7 +168,7 @@ inline void icp_adf_getQueueNext(icp_com + * icp_adf_updateQueueTail + * Data plain support function - Writes the tail shadow copy to the device. + */ +-inline void icp_adf_updateQueueTail(icp_comms_trans_handle trans_hnd) ++void icp_adf_updateQueueTail(icp_comms_trans_handle trans_hnd) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; + icp_accel_dev_t *accel_dev = (icp_accel_dev_t*) pRingHandle->accel_dev; +@@ -183,7 +183,7 @@ inline void icp_adf_updateQueueTail(icp_ + * icp_adf_isRingEmpty + * Data plain support function - check if the ring is empty + */ +-inline CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_hnd) ++CpaBoolean icp_adf_isRingEmpty(icp_comms_trans_handle trans_hnd) + { + Cpa32U mask = 0; + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -205,7 +205,7 @@ inline CpaBoolean icp_adf_isRingEmpty(ic + * * icp_adf_pollQueue + * * Data plain support function - Poll messages from the queue. + * */ +-inline CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_hnd, ++CpaStatus icp_adf_pollQueue(icp_comms_trans_handle trans_hnd, + Cpa32U response_quota) + { + adf_dev_ring_handle_t *pRingHandle = (adf_dev_ring_handle_t *)trans_hnd; +@@ -260,7 +260,7 @@ inline CpaStatus icp_adf_pollQueue(icp_c + * send. This should only be called on request rings. If the function returns + * true then it is ok to call icp_adf_updateQueueTail() function on this ring. + */ +-inline CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd) ++CpaBoolean icp_adf_queueDataToSend(icp_comms_trans_handle trans_hnd) + { + adf_dev_ring_handle_t *ringData = (adf_dev_ring_handle_t *)trans_hnd; + icp_accel_dev_t *accel_dev = (icp_accel_dev_t*) ringData->accel_dev; +--- a/quickassist/build_system/build_files/OS/linux_2.6_kernel_space_rules.mk ++++ b/quickassist/build_system/build_files/OS/linux_2.6_kernel_space_rules.mk +@@ -73,15 +73,15 @@ endif + $(LIB_STATIC): dirs + @echo 'Creating static library ${LIB_STATIC}'; \ + $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD) obj-m=""; \ +- echo 'Copying outputs';\ ++ echo 'Copying outputs $(OBJ)';\ ++ test -f lib.a && (ar -t lib.a | xargs ar -rcsD $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC)); \ + mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ +- test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $($(PROG_ACY)_FINAL_OUTPUT_DIR)/lib.a && mv $($(PROG_ACY)_FINAL_OUTPUT_DIR)/lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ + test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ + $(RM) -rf *.mod.* .*.cmd; + +- + $(MODULENAME): dirs + @echo 'Creating kernel module'; \ + $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD); \ +--- a/quickassist/lookaside/access_layer/src/sample_code/fips/cpa_fips_sample.h ++++ b/quickassist/lookaside/access_layer/src/sample_code/fips/cpa_fips_sample.h +@@ -109,7 +109,7 @@ extern "C" + #include + #include + #include +-#include ++#include + #else /*KERNEL_SPACE*/ + #include + #include +--- a/quickassist/lookaside/access_layer/src/sample_code/performance/qae/linux/kernel_space/qae_mem_drv.c ++++ b/quickassist/lookaside/access_layer/src/sample_code/performance/qae/linux/kernel_space/qae_mem_drv.c +@@ -85,7 +85,7 @@ + #include + + +-#include ++#include + #include + #include + +--- a/quickassist/utilities/downloader/Target_CoreLibs/halAe/icp_firml_interface.c ++++ b/quickassist/utilities/downloader/Target_CoreLibs/halAe/icp_firml_interface.c +@@ -185,7 +185,7 @@ icp_FirmLoader_MapMofAddr(void *handle, + int status = ICP_FIRMLOADER_SUCCESS; + + myHandle = (icp_firml_handle_t *)handle; +- ++ + status = UcLo_MapMofAddr(myHandle, filePtr, fileSize, + uofName, (char **)uofPtr, uofSize); + +--- a/quickassist/utilities/downloader/Target_CoreLibs/uclo/uclo_mof.c ++++ b/quickassist/utilities/downloader/Target_CoreLibs/uclo/uclo_mof.c +@@ -582,6 +582,7 @@ UcLo_MapMofAddr (icp_firml_handle_t *han + /* UOF_FID (0xc6c2) for uof object + * SUOF_FID for suof object + */ ++ + if ((((uof_fileHdr_T *) mofPtr)->fileId == UOF_FID) || + (((suof_fileHdr_T *) mofPtr)->fileId == SUOF_FID)) + { +@@ -599,7 +600,6 @@ UcLo_MapMofAddr (icp_firml_handle_t *han + /* return BADOBJ if neither UOF/SUOF nor MOF */ + else if (((mof_fileHdr_T *)mofPtr)->fileId != MOF_FID) + { +- PRINTF("unsupported file format\n"); + return (UCLO_BADOBJ); + } + +--- a/quickassist/utilities/osal/src/linux/kernel_space/OsalUsrKrlProxy.c ++++ b/quickassist/utilities/osal/src/linux/kernel_space/OsalUsrKrlProxy.c +@@ -45,7 +45,7 @@ + #include + #include + +-#include ++#include + #include + #include + +--- a/quickassist/utilities/osal/src/linux/user_space/OsalCryptoInterface.c ++++ b/quickassist/utilities/osal/src/linux/user_space/OsalCryptoInterface.c +@@ -78,7 +78,7 @@ OSAL_STATUS + osalHashSHA1(UINT8 *in, UINT8 *out) + { + SHA_CTX ctx; +- if(!SHA_Init(&ctx)) ++ if(!SHA1_Init(&ctx)) + { + return OSAL_FAIL; + } diff --git a/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch b/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch new file mode 100644 index 000000000..a312ded4c --- /dev/null +++ b/package/qat/firmware/quickassist-c2xxx/patches/0002-contig-mem-driver-backport.patch @@ -0,0 +1,5908 @@ +--- a/quickassist/Makefile ++++ b/quickassist/Makefile +@@ -80,8 +80,11 @@ else + endif + + #Paths to Top-Level Makefiles for each team#### ++KBUILD_EXTRA_SYMBOLS += $(ICP_ROOT)/quickassist/utilities/libusdm_drv/Module.symvers ++export KBUILD_EXTRA_SYMBOLS + + OSAL_PATH=$(ICP_ROOT)/quickassist/utilities/osal/ ++CMN_MEM_PATH=$(ICP_ROOT)/quickassist/utilities/libusdm_drv/ + HAL_PATH=$(ICP_ROOT)/quickassist/utilities/downloader/ + HAL_LIB_PATH=$(ICP_ROOT)/quickassist/utilities/downloader/ + QAT_FW_PATH=$(ICP_ROOT)/quickassist/lookaside/firmware/ +@@ -121,6 +124,22 @@ install_scripts: + @cp $(CONFIG_PATH)/dh89xxcc_qa_dev0_single_accel.conf $(ICP_BUILD_OUTPUT)/; + @cp $(CONFIG_PATH)/c2xxx_qa_dev0.conf $(ICP_BUILD_OUTPUT)/; + ++# ++# Common memory driver ++# ++ ++#userspace common memory library ++cmn_user: clean output_dir lac_lib_dir ++ @echo ; echo 'Building common mem driver for user space'; ++ @cd $(CMN_MEM_PATH) && $(MAKE) ARCH=$(ICP_ARCH_USER) ICP_ENV_DIR=$(ICP_TOP_ENV) OS=linux ICP_OS?=linux_2.6 ICP_OS_LEVEL=user_space CPM_UPSTREAM=1 cm_user;\ ++ echo ; echo 'Copying Common mem library'; ++ cp $(CMN_MEM_PATH)/libusdm_drv_s.so $(CMN_MEM_PATH)/libusdm_drv.a $(ICP_BUILD_OUTPUT)/; ++ ++#common mem driver ko ++cmn_ko: clean output_dir ++ @echo ; echo 'Building usdm_drv.ko'; ++ @cd $(CMN_MEM_PATH) && $(MAKE) ICP_ENV_DIR=$(ICP_TOP_ENV) OS=linux ICP_OS?=linux_2.6 ICP_OS_LEVEL=kernel_space ICP_QDM_IOMMU=1 CPM_UPSTREAM=1 cm_kernel ++ @cp $(CMN_MEM_PATH)/usdm_drv.ko $(ICP_BUILD_OUTPUT) + + #libosal needed by hal and adf + libosal: output_dir lac_lib_dir +@@ -151,7 +170,7 @@ hal_ci: output_dir libosal_ci + @echo ; echo 'Copying HAL Binary to $(LAC_LIB_DIR)'; + @cp $(HAL_LIB_PATH)/lib_linux_le/$(ICP_TOOLS_TARGET)/icp_ae_loader_kernel.a $(LAC_LIB_DIR)/ + +-adf: output_dir lac_lib_dir libosal hal ++adf: output_dir lac_lib_dir libosal hal cmn_ko + @echo ; echo 'Building ADF'; + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEV && export ICP_ENV_DIR=$(ICP_TOP_ENV) export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=kernel_space && $(MAKE); + cp $(ADF_PATH)/build/linux_2.6/libadf.a $(LAC_LIB_DIR)/; +@@ -179,7 +198,7 @@ adfvf: output_dir lac_lib_dir libosalvf + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEVVF && export ICP_ENV_DIR=$(ICP_TOP_ENV) export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=kernel_space && $(MAKE); + cp $(ADF_PATH)/build/linux_2.6/libadf.a $(LAC_LIB_DIR)/; + +-adf_user: output_dir lac_lib_dir libosal_user ++adf_user: output_dir lac_lib_dir libosal_user cmn_user + @echo ; echo 'Building user ADF'; + @cd $(ADF_PATH) && export ADF_PLATFORM=ACCELDEV && export ICP_ENV_DIR=$(ICP_TOP_ENV) && export ONE_KO_RELEASE_PACKAGE=1 && ICP_OS_LEVEL=user_space && $(MAKE) ARCH=$(ICP_ARCH_USER) adf_user; + cp $(ADF_PATH)/build/linux_2.6/libadf_proxy.a $(ICP_BUILD_OUTPUT)/; +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/Makefile +@@ -0,0 +1,142 @@ ++######################################################################### ++# ++# @par ++# This file is provided under a dual BSD/GPLv2 license. When using or ++# redistributing this file, you may do so under either license. ++# ++# GPL LICENSE SUMMARY ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++# The full GNU General Public License is included in this distribution ++# in the file called LICENSE.GPL. ++# ++# Contact Information: ++# Intel Corporation ++# ++# BSD LICENSE ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# * Neither the name of Intel Corporation nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++# ++# ++# version: QAT1.7.L.4.7.0-00006 ++############################################################################ ++ ++ ++####################Common variables and definitions######################## ++export BASE_NAME = usdm_drv ++export OSTYPE=$(shell uname -s) ++ ++ifeq ($(OSTYPE),FreeBSD) ++ICP_OS := freebsd ++OS := freebsd ++export MAKE := make ++DMESG := dmesg -c ++FBSD_VERSION := $(shell uname -r | cut -d'-' -f1,2) ++ifeq ($(FBSD_VERSION),8.4-RELEASE) ++DMESG := dmesg && sudo sysctl kern.msgbuf_clear=1 ++endif ++else ++ICP_OS?=linux_2.6 ++OS?=linux ++ICP_OS_LEVEL?=user_space ++DMESG := dmesg -C ++endif ++ ++ ++all: cm_user cm_kernel ++ @echo ; echo "Build Completed"; ++cm_user: ++ifneq ($(OSTYPE),FreeBSD) ++ @cd $(OS) && \ ++ $(MAKE) clean ICP_OS_LEVEL=user_space; ++ @cd $(OS) && \ ++ $(MAKE) ICP_OS_LEVEL=user_space lib_shared UT=$(UT) BE=$(BE); ++ @cd $(OS) && \ ++ $(MAKE) ICP_OS_LEVEL=user_space lib_static UT=$(UT) BE=$(BE); ++ @cp $(OS)/build/$(ICP_OS)/user_space/lib$(BASE_NAME)_s.so lib$(BASE_NAME)_s.so ; ++ @cp $(OS)/build/$(ICP_OS)/user_space/lib$(BASE_NAME).a lib$(BASE_NAME).a ; ++else ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=user_space; ++ @cd $(ICP_OS) && \ ++ make ICP_OS_LEVEL=user_space; ++ @cp $(ICP_OS)/user_space/libusdm_drv.so.0 libusdm_drv_s.so ; ++ @cp $(ICP_OS)/user_space/libusdm_drv.a libusdm_drv.a ; ++endif ++ ++cm_kernel: ++ifneq ($(OSTYPE),FreeBSD) ++ @echo $(ICP_BUILDSYSTEM_PATH) ++ @cd $(OS) && \ ++ $(MAKE) clean ICP_OS_LEVEL=kernel_space && \ ++ $(MAKE) ICP_OS_LEVEL=kernel_space UT=$(UT) BE=$(BE); ++ @mv $(OS)/build/$(ICP_OS)/kernel_space/$(BASE_NAME).a $(OS)/build/$(ICP_OS)/kernel_space/lib$(BASE_NAME).a ; ++ @cp linux/Module.symvers Module.symvers; ++ @cp $(OS)/build/$(ICP_OS)/kernel_space/$(BASE_NAME).ko $(BASE_NAME).ko; ++else ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=kernel_space && \ ++ make ICP_OS_LEVEL=kernel_space UT=$(UT); ++ @cp $(ICP_OS)/kernel_space/usdm_drv.ko usdm_drv.ko; ++endif ++ ++bsd_kernel: ++ @cd $(ICP_OS) && \ ++ make clean ICP_OS_LEVEL=kernel_space && \ ++ make ICP_OS_LEVEL=kernel_space UT=$(UT); ++ @cp $(ICP_OS)/kernel_space/$(BASE_NAME).ko $(BASE_NAME).ko; ++ ++ ++clean: ++ rm -f *.a *.so *.ko ++ @cd $(OS) && \ ++ rm -f kernel_space/.*.cmd && \ ++ rm -f kernel_space/.depend* && \ ++ rm -f user_space/.depend* && \ ++ $(MAKE) ICP_OS_LEVEL=user_space clean && \ ++ $(MAKE) ICP_OS_LEVEL=kernel_space clean ++ ++doxygen: ++ @doxygen qae_mem.h > doxygen_output.txt 2>&1; ++ @echo "The doxygen file is available at $(PWD)/html/index.html" ++ @echo "The doxygen command output is available at $(PWD)/doxygen_output.txt" +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/Makefile +@@ -0,0 +1,197 @@ ++######################################################################### ++# ++# @par ++# This file is provided under a dual BSD/GPLv2 license. When using or ++# redistributing this file, you may do so under either license. ++# ++# GPL LICENSE SUMMARY ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of version 2 of the GNU General Public License as ++# published by the Free Software Foundation. ++# ++# This program is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++# The full GNU General Public License is included in this distribution ++# in the file called LICENSE.GPL. ++# ++# Contact Information: ++# Intel Corporation ++# ++# BSD LICENSE ++# ++# Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++# All rights reserved. ++# ++# Redistribution and use in source and binary forms, with or without ++# modification, are permitted provided that the following conditions ++# are met: ++# ++# * Redistributions of source code must retain the above copyright ++# notice, this list of conditions and the following disclaimer. ++# * Redistributions in binary form must reproduce the above copyright ++# notice, this list of conditions and the following disclaimer in ++# the documentation and/or other materials provided with the ++# distribution. ++# * Neither the name of Intel Corporation nor the names of its ++# contributors may be used to endorse or promote products derived ++# from this software without specific prior written permission. ++# ++# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++# ++# ++# version: QAT1.7.L.4.7.0-00006 ++############################################################################ ++ ++ ++####################Common variables and definitions######################## ++ICP_OS?=linux_2.6 ++OS?=linux ++ICP_OS_LEVEL?=user_space ++CMN_ROOT?=$(ICP_ROOT)/quickassist/utilities/libusdm_drv ++QAT_DRV?=$(ICP_ROOT)/quickassist/qat ++ ++#include the makefile with all the default and common Make variable definitions ++include $(ICP_BUILDSYSTEM_PATH)/build_files/common.mk ++ ++# List of Source Files to be compiled (to be in a single line or on different lines separated by a "\" and tab. ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++SOURCES:= $(ICP_OS_LEVEL)/qae_mem_utils.c $(ICP_OS_LEVEL)/qae_mem_hugepage_utils.c ++else ++MODULE_SOURCES:= $(ICP_OS_LEVEL)/qae_mem_drv.c ++SOURCES:=$(ICP_OS_LEVEL)/qae_mem_utils.c ++endif ++ ++ifeq ($(UT),1) ++MODULE_SOURCES+= ../test/$(OS)/$(ICP_OS_LEVEL)/qae_mem_drv_utils.c $(ICP_OS_LEVEL)/qdm.c ++else ++MODULE_SOURCES+= $(ICP_OS_LEVEL)/qae_mem_drv_utils.c $(ICP_OS_LEVEL)/qdm.c ++endif ++ ++INCLUDES += -I$(CMN_ROOT) ++ ++INCLUDES += -I$(CMN_ROOT)/$(OS)/include ++ ++ifeq ($(ICP_ADF_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_ADF_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/src/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifeq ($(ICP_OSAL_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_OSAL_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/src/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifeq ($(ICP_QDM_IOMMU), 1) ++EXTRA_CFLAGS += -DICP_QDM_IOMMU ++KBUILD_EXTRA_SYMBOLS+=$(QAT_DRV)/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ ++ifdef QAE_USE_128K_SLABS ++EXTRA_CFLAGS+=-DQAE_NUM_PAGES_PER_ALLOC=32 ++endif ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++EXTRA_CFLAGS += -DUSER_SPACE ++EXTRA_CFLAGS += -Wextra -Werror -Wno-missing-field-initializers ++ifdef ICP_X86 ++EXTRA_CFLAGS += -m32 -D_FILE_OFFSET_BITS=64 ++LIB_SHARED_FLAGS += -m elf_i386 ++endif ++ifdef ICP_DISABLE_SECURE_MEM_FREE ++EXTRA_CFLAGS += -DICP_DISABLE_SECURE_MEM_FREE ++endif ++ifdef ICP_WITHOUT_THREAD ++EXTRA_CFLAGS += -DICP_WITHOUT_THREAD ++endif ++else ++ ++EXTRA_CFLAGS += -DKERNEL_SPACE ++ifeq ($(BE) ,1) ++KBUILD_EXTRA_SYMBOLS+=$(BE_DIR)/run/linuxKernel/Module.symvers ++export KBUILD_EXTRA_SYMBOLS ++endif ++ifdef ICP_NO_PROC_SUPPORT ++EXTRA_CFLAGS += -DICP_NO_PROC_SUPPORT ++endif ++ ++# Check for defense with stack protection in kernel ++ifeq ($(KERNEL_DEFENSES_STACK_PROTECTION), n) ++STACK_PROTECTION=-fstack-protector -fstack-protector-strong ++EXTRA_CFLAGS := $(filter-out $(STACK_PROTECTION), $(EXTRA_CFLAGS)) ++endif ++endif ++ ++ifeq ($(ICP_OS_LEVEL),user_space) ++#include os dependent rules ++include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk ++lib: lib_shared ++all: lib_shared ++OUTPUT_NAME=lib$(BASE_NAME) ++export OUTPUT_NAME ++else ++ ++OUTPUT_NAME=$(BASE_NAME) ++export OUTPUT_NAME ++ ++#kernel space rules here ++#produce two artefacts: module and static library and copy them ++ifeq ($(OS),linux) ++EXTRA_CFLAGS+=-I$(INCLUDES) -Werror -ftree-ter ++obj-m+=$(OUTPUT_NAME).o ++$(OUTPUT_NAME)-objs :=$(patsubst %.c,%.o, $(MODULE_SOURCES)) $(ADDITIONAL_KERNEL_LIBS) ++lib-m := $(patsubst %.c,%.o, $(SOURCES)) $(patsubst %.S,%.o, $(ASM_SOURCES)) ++$(LIB_STATIC): dirs ++ @echo 'Creating static library ${LIB_STATIC}'; \ ++ $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD) obj-m=""; \ ++ echo 'Copying outputs';\ ++ mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ $(RM) -rf *.mod.* .*.cmd; ++ ++$(MODULENAME): dirs ++ @echo 'Creating kernel module'; \ ++ $(MAKE) -C $(KERNEL_SOURCE_ROOT)/ M=$(PWD); \ ++ echo 'Copying outputs';\ ++ mv -f $(OBJ) $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f built-in.o && mv -f built-in.o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f lib.a && mv lib.a $($(PROG_ACY)_FINAL_OUTPUT_DIR)/$(LIB_STATIC);\ ++ test -f $(OUTPUT_NAME).ko && mv -f $(OUTPUT_NAME).ko $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ test -f $(OUTPUT_NAME).o && mv -f $(OUTPUT_NAME).o $($(PROG_ACY)_FINAL_OUTPUT_DIR);\ ++ $(RM) -rf *.mod.* .*.cmd; ++else ++include $(ICP_ENV_DIR)/$(ICP_OS)_$(ICP_OS_LEVEL).mk ++endif ++ ++all: module ++install: module ++endif ++###################Include rules makefiles######################## ++include $(ICP_BUILDSYSTEM_PATH)/build_files/rules.mk ++ ++###################End of Rules inclusion######################### +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/include/qae_mem_utils.h +@@ -0,0 +1,757 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++* @file qae_mem_utils.h ++* ++* This file provides linux kernel memory allocation for quick assist API ++* ++*****************************************************************************/ ++#ifndef QAE_MEM_UTILS_H_ ++#define QAE_MEM_UTILS_H_ ++#if defined(__KERNEL__) ++#ifdef __FreeBSD__ ++#include ++#include ++#include ++#include ++MALLOC_DECLARE(M_QAE_MEM); ++#else ++#include ++#include ++#include ++ ++#if (KERNEL_VERSION(2, 6, 38) >= LINUX_VERSION_CODE) ++#define kstrtoll strict_strtoll ++#endif /* KERNEL_VERSION */ ++#endif /* OS selection */ ++#endif /* __KERNEL__ */ ++ ++#define USDM_MOD "usdm_drv: " ++ ++#define mm_err(...) pr_err(USDM_MOD __VA_ARGS__) ++ ++#define mm_info(...) pr_info(USDM_MOD __VA_ARGS__) ++ ++#define mm_warning(...) pr_warning(USDM_MOD __VA_ARGS__) ++ ++/*define types which need to vary between 32 and 64 bit*/ ++#define QAE_PAGE_SHIFT 12 ++#define QAE_PAGE_SIZE (1UL << QAE_PAGE_SHIFT) ++ ++/* QAE_NUM_PAGES_PER_ALLOC can be defined as 32 pages when library ++is built, default is 512 */ ++#ifndef QAE_NUM_PAGES_PER_ALLOC ++#define QAE_NUM_PAGES_PER_ALLOC 512 ++#endif ++ ++#define STATIC static ++ ++#define QAE_PHYS_ADDR uint64_t ++ ++#define QAE_MEM_ZALLOC_GEN(size) kzalloc(size, GFP_KERNEL) ++#define QAE_MEM_FREE(ptr) \ ++ do \ ++ { \ ++ if (ptr) \ ++ { \ ++ kfree(ptr); \ ++ ptr = NULL; \ ++ } \ ++ } while (0) ++/** ++ ***************************************************************************** ++ * @ingroup perfCodeFramework ++ * Framework aligned memory structure. ++ * @description ++ * This structure is used to assist the framework in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct qae_mem_alloc_info_s ++{ ++ void *mAllocMemPtr; /* memory addr returned by the kernel */ ++ size_t mSize; /* allocated size */ ++ ++} qae_mem_alloc_info_t; ++ ++enum slabType ++{ ++ SMALL = 0, ++ LARGE = 1, ++ HUGE_PAGE = 2, ++}; ++ ++/* User space memory information structure. */ ++typedef struct dev_mem_info_s ++{ ++ int64_t nodeId; /* shared b/w user/kernel */ ++ /* Node id for NUMA */ ++ uint64_t size; /* shared b/w user/kernel */ ++ /* Size of this block (bytes) */ ++ enum slabType type; ++ /* Slab for normal memory or large memory */ ++ uint32_t allocations; /* user space only */ ++ /* Huge page file descriptor */ ++ int64_t hpg_fd; /* user space only */ ++ /* The huge page file descriptor of each slab */ ++ uint64_t phy_addr; /* shared b/w user/kernel */ ++ /* Physical address of the kmalloced area */ ++ union { ++ void *virt_addr; /* user space only */ ++ uint64_t padding_virt; ++ }; ++ /* Base address in user space - i.e. virtual address */ ++ union { ++ struct dev_mem_info_s *pPrev_user; /* user space only */ ++ uint64_t padding_prevu; ++ }; ++ union { ++ struct dev_mem_info_s *pNext_user; /* user space only */ ++ uint64_t padding_nextu; ++ }; ++ union { ++ struct dev_mem_info_s *pPrev_user_hash; /* user space only */ ++ uint64_t padding_prevuh; ++ }; ++ union { ++ struct dev_mem_info_s *pNext_user_hash; /* user space only */ ++ uint64_t padding_nextuh; ++ }; ++} dev_mem_info_t; ++ ++/* Kernel space memory information structure. */ ++typedef struct kdev_mem_info_s ++{ ++ void *kmalloc_ptr; /* kernel space only (small slab) */ ++ /* Pointer to mem originally returned by kmalloc */ ++ void *huge_mem_ctrl; ++ uint64_t size; ++ /* Slab size */ ++ uint64_t phy_addr; /* shared b/w user/kernel */ ++ /* Physical address of the kmalloc'ed area */ ++ struct kdev_mem_info_s *pPrev_kernel; ++ struct kdev_mem_info_s *pNext_kernel; ++ struct kdev_mem_info_s *pPrev_kernel_hash; ++ struct kdev_mem_info_s *pNext_kernel_hash; ++} kdev_mem_info_t; ++ ++typedef struct user_page_info_s ++{ ++ /* Use 64-bit unsigned to support 32bit application on ++ * a 64-bit kernel */ ++ uint64_t virt_addr; ++ /* physical address shared b/w user/kernel */ ++ uint64_t phy_addr; ++} user_page_info_t; ++ ++/* size of allocation unit */ ++#define UNIT_SIZE 1024 ++#define QAE_KBYTE 1024 ++#define QWORD_WIDTH (8 * sizeof(uint64_t)) ++#define QWORD_ALL_ONE 0xFFFFFFFFFFFFFFFFULL ++ ++/* ++Bitmap is used to keep track the allocation of each block ++Each 1k block is represented by one bit allocated(1)/free(0) ++BITMAP_LEN is a macro the represents the number of 64-bit quad words ++that make up the bitmap ++with 512 pages of 4k page and 1k units this value is 32 ++ */ ++#define CHUNK_SIZE (UNIT_SIZE * QWORD_WIDTH) ++ ++#define BITMAP_LEN (QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / CHUNK_SIZE) ++ ++#define BLOCK_SIZES (BITMAP_LEN * QWORD_WIDTH) ++ ++/*block control structure */ ++typedef struct block_ctrl_s ++{ ++ dev_mem_info_t mem_info; /* memory device info type */ ++ /* adding an extra element at the end to make a barrier */ ++ uint64_t bitmap[BITMAP_LEN + 1]; /* bitmap each bit represents a 1k block */ ++ uint16_t sizes[BLOCK_SIZES]; /* Holds the size of each allocated block */ ++} block_ctrl_t; ++ ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * array structure ++ * @description ++ * This structure is used to copy chunks of data read from files ++ * from user to kernel space ++ ****************************************************************************/ ++typedef struct dev_mem_file_s ++{ ++ unsigned char data[2048]; ++ unsigned int size; ++} dev_mem_file_t; ++ ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * user space memory list pointer structure. ++ * @description ++ * This structure is used to assist in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct user_proc_mem_list_s ++{ ++ int pid; ++ uint64_t allocs_nr; ++ uint64_t hugepages_nr; ++ kdev_mem_info_t *head; ++ kdev_mem_info_t *tail; ++ struct user_proc_mem_list_s *pPrev; ++ struct user_proc_mem_list_s *pNext; ++} user_proc_mem_list_t; ++/** ++ ***************************************************************************** ++ * @ingroup qaeMemUtils ++ * user space memory list pointer structure. ++ * @description ++ * This structure is used to assist in allocating aligned ++ * memory ++ ****************************************************************************/ ++typedef struct user_mem_dev_s ++{ ++ user_proc_mem_list_t *head; ++ user_proc_mem_list_t *tail; ++} user_mem_dev_t; ++ ++/* ++ ****************************************************************************** ++ * @ingroup ADD_ELEMENT_TO_HEAD_LIST ++ * insert element at the head of a linked list ++ * @description ++ * inserts a new element at the head of a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToAdd - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define ADD_ELEMENT_TO_HEAD_LIST(elementToAdd, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ elementToAdd->pPrev##mode = NULL; \ ++ if (NULL == headPtr) \ ++ { \ ++ tailPtr = elementToAdd; \ ++ elementToAdd->pNext##mode = NULL; \ ++ } \ ++ else \ ++ { \ ++ elementToAdd->pNext##mode = headPtr; \ ++ headPtr->pPrev##mode = elementToAdd; \ ++ } \ ++ headPtr = elementToAdd; \ ++ } while (0) ++ ++/* ++ ****************************************************************************** ++ * @ingroup ADD_ELEMENT_TO_END_LIST ++ * insert element at the end of a linked list ++ * @description ++ * inserts a new element at the head of a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToAdd - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define ADD_ELEMENT_TO_END_LIST(elementToAdd, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ elementToAdd->pNext##mode = NULL; \ ++ if (NULL == tailPtr) \ ++ { \ ++ headPtr = elementToAdd; \ ++ elementToAdd->pPrev##mode = NULL; \ ++ } \ ++ else \ ++ { \ ++ elementToAdd->pPrev##mode = tailPtr; \ ++ tailPtr->pNext##mode = elementToAdd; \ ++ } \ ++ tailPtr = elementToAdd; \ ++ } while (0) ++ ++/* ++ ****************************************************************************** ++ * @ingroup REMOVE_ELEMENT_FROM_LIST ++ * remove element at the end of a linked list ++ * @description ++ * removes an element from a ++ * double linked list in user or kernel mode ++ * depending on mode parameter if mode is an ++ * empty string kernel mode is used ++ * elementToREmove - ptr to the new element ++ * headPtr - ptr to the first element in list ++ * tailPtr - ptr to the last element int the list ++ * mode - _kernel,_user or empty ++ ******************************************************************************/ ++ ++#define REMOVE_ELEMENT_FROM_LIST(elementToRemove, headPtr, tailPtr, mode) \ ++ do \ ++ { \ ++ if (NULL != elementToRemove->pPrev##mode) \ ++ { \ ++ elementToRemove->pPrev##mode->pNext##mode = \ ++ elementToRemove->pNext##mode; \ ++ if (NULL != elementToRemove->pNext##mode) \ ++ { \ ++ elementToRemove->pNext##mode->pPrev##mode = \ ++ elementToRemove->pPrev##mode; \ ++ } \ ++ else \ ++ { \ ++ tailPtr = elementToRemove->pPrev##mode; \ ++ } \ ++ } \ ++ else \ ++ { \ ++ if (NULL != elementToRemove->pNext##mode) \ ++ { \ ++ elementToRemove->pNext##mode->pPrev##mode = NULL; \ ++ headPtr = elementToRemove->pNext##mode; \ ++ } \ ++ else \ ++ { \ ++ headPtr = NULL; \ ++ tailPtr = NULL; \ ++ } \ ++ } \ ++ } while (0) ++ ++/* IOCTL number for use between the kernel and the user space application */ ++#define DEV_MEM_MAGIC 'q' ++#define DEV_MEM_CMD_MEMALLOC (0) ++#define DEV_MEM_CMD_MEMFREE (1) ++#define DEV_MEM_CMD_RELEASE (2) ++#define DEV_MEM_CMD_UNREGISTER (3) ++#define DEV_MEM_CMD_GET_NUM_HPT (4) ++#define DEV_MEM_CMD_GET_USER_PAGE (5) ++ ++/* IOCTL commands for requesting kernel memory */ ++#define DEV_MEM_IOC_MEMALLOC \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_MEMALLOC, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_MEMFREE \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_MEMFREE, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_RELEASE _IO(DEV_MEM_MAGIC, DEV_MEM_CMD_RELEASE) ++ ++#define DEV_MEM_IOC_UNREGISTER \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_UNREGISTER, dev_mem_info_t) ++ ++#define DEV_MEM_IOC_GET_NUM_HPT \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_GET_NUM_HPT, uint32_t) ++ ++#define DEV_MEM_IOC_GET_USER_PAGE \ ++ _IOWR(DEV_MEM_MAGIC, DEV_MEM_CMD_GET_USER_PAGE, user_page_info_t) ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeMemInit ++ * ++ * @description ++ * Initialize the user-space allocator, opening the device driver ++ * used to communicate with the kernel-space. ++ * ++ * @param[in] path - path to the specific device ++ * ++ * @retval 0 if the open of the device was successful and ++ * non-zero otherwise ++ * @pre ++ * none ++ * @post ++ * Allocator is initialized ++ * ++ ****************************************************************************/ ++int32_t qaeMemInit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeMemDestroy ++ * ++ * @description ++ * Release the user-space allocator. It closes the file descriptor ++ * associated with the device driver ++ * ++ * @param[in] none ++ * ++ * @retval none ++ * ++ * @pre ++ * The user space allocator is initialized using qaeMemInit ++ * @post ++ * The user-space allocator is released ++ * ++ ****************************************************************************/ ++void qaeMemDestroy(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUInit ++ * ++ * @description ++ * Function creates iommu domain. Applicable when IOMMU is enabled ++ * ++ * @param[in] none ++ * ++ * @retval 0 - if successful. ++ * non-zero - otherwise ++ * ++ * @pre ++ * IOMMU is enabled. ++ * @post ++ * iommu domain created ++ * ++ ****************************************************************************/ ++int32_t qaeIOMMUInit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUExit ++ * ++ * @description ++ * Function removes iommu domain. Applicable when IOMMU is enabled ++ * ++ * @param[in] none ++ * ++ * @retval none ++ * ++ * @pre ++ * IOMMU is enabled and an iommu domain is created using qaeIOMMUInit ++ * @post ++ * iommu domain removed ++ * ++ ****************************************************************************/ ++void qaeIOMMUExit(void); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUgetRemappingSize ++ * ++ * @description ++ * Function calculates size for remapping when IOMMU is enabled. ++ * Before calling any of the qaeMemAlloc functions, this function can be ++ * used to calculate the actual size of memory to be allocated. ++ * The remapping size is at least PAGE_SIZE. ++ * ++ * @param[in] size - Actual size of the memory to be allocated ++ * ++ * @retval Remapping size ++ * ++ * @pre ++ * IOMMU is enabled and an iommu domain is created using qaeIOMMUInit. ++ * @post ++ * Remapping size provided. ++ * ++ ****************************************************************************/ ++size_t qaeIOMMUgetRemappingSize(size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUMap ++ * ++ * @description ++ * Function adds mapping from io virtual address to a physical address. ++ * Applicable when IOMMU is enabled ++ * ++ * @param[in] phaddr - Host physical address. ++ * @param[in] iova - IO virtual address. ++ * @param[in] size - Memory size to be remapped obtained from ++ * qaeIOMMUgetRemappingSize() function. ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful. ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. phaddr is already obtained using ++ * iova using virt_to_phys or similar functions. size is calculated ++ * using qaeIOMMUgetRemappingSize function. ++ * @post ++ * IO virtual address mapped ++ ****************************************************************************/ ++int32_t qaeIOMMUMap(uint64_t phaddr, uint64_t iova, size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUUnmap ++ * ++ * @description ++ * Function removes mapping from io virtual address to a physical ++ * address. Applicable when IOMMU is enabled ++ * ++ * @param[in] iova - IO virtual address. ++ * @param[in] size - Memory size to be unmapped ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful. ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. ++ * @post ++ * IO virtual address unmapped ++ ****************************************************************************/ ++int32_t qaeIOMMUUnmap(uint64_t iova, size_t size); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUVirtToPhys ++ * ++ * @description ++ * Function translates io virtual address to a physical address. ++ * Applicable when IOMMU is enabled. ++ * ++ * @param[in] iova, IO virtual address ++ * ++ * @retval host physical address - if successful ++ * NULL Otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. iova points to ++ * previously allocated memory. ++ * @post ++ * virtual address is translated to physical address ++ * ++ ****************************************************************************/ ++uint64_t qaeIOMMUVirtToPhys(uint64_t iova); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUAttachDev ++ * ++ * @description ++ * This function attaches a pci dev (VF) to an iommu domain. ++ * Applicable when IOMMU/SRIOV are enabled and after the driver bringup ++ * in Host is succesful. ++ * ++ * @param[in] dev, Device to be attached ++ * ++ * @retval CPA_STATUS_SUCCESS - if successful ++ * CPA_STATUS_UNSUPPORTED - if not supported ++ * CPA_STATUS_FAIL - otherwise ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit. Driver bringup ++ * in Host is succesful. ++ * @post ++ * device is attached ++ * ++ ****************************************************************************/ ++int32_t qaeIOMMUAttachDev(void *dev); ++ ++/***************************************************************************** ++ * * @ingroup CommonMemoryDriver ++ * qaeIOMMUDetachDev ++ * ++ * @description ++ * Function detaches pci dev to iommu domain ++ * ++ * @param[in] dev, Device to be detached ++ * ++ * @retval none ++ * ++ * @pre ++ * An iommu domain is created using qaeIOMMUInit, Driver bringup ++ * in Host is succesful and dev is already ++ * attached using qaeIOMMUAttachDev ++ * @post ++ * Device is detached ++ * ++ ****************************************************************************/ ++void qaeIOMMUDetachDev(void *dev); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * printMemAllocations ++ * ++ * @description ++ * Prints only the overall count of NUMA and non-NUMA memory allocations ++ * performed. This doesn't provide other details like the allocation ++ * sizes, pointers etc. ++ * ++ * @retval none ++ * ++ * @pre ++ * The user space allocator is initialized using qaeMemInit ++ * @post ++ * memory allocation count printed ++ * ++ ****************************************************************************/ ++void printMemAllocations(void); ++ ++#ifndef __KERNEL__ ++#ifdef ICP_WITHOUT_THREAD ++#define mem_mutex_lock(x) (0) ++#define mem_mutex_unlock(x) (0) ++#else ++#define mem_mutex_lock(x) pthread_mutex_lock(x) ++#define mem_mutex_unlock(x) pthread_mutex_unlock(x) ++#endif ++ ++#define mem_ioctl(fd, cmd, pMemInfo) ioctl(fd, cmd, pMemInfo) ++#define qae_open(file, options) open(file, options) ++#define qae_lseek(fd, offset, whence) lseek(fd, offset, whence) ++#define qae_read(fd, buf, nbytes) read(fd, buf, nbytes) ++#define qae_mmap(addr, length, prot, flags, fd, offset) \ ++ mmap(addr, length, prot, flags, fd, offset) ++#define qae_munmap(addr, length) munmap(addr, length) ++#define qae_madvise(addr, len, advice) madvise(addr, len, advice) ++#define qae_mkstemp(template) mkstemp(template) ++#endif ++ ++#if defined(__KERNEL__) ++#if defined(ICP_ADF_IOMMU) ++int icp_adf_iommu_map(void *iova, void *phaddr, size_t size); ++int icp_adf_iommu_unmap(void *iova, size_t size); ++size_t icp_adf_iommu_get_remapping_size(size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ void *phaddr = (void *)virt_to_phys(vaddr); ++ *iova = phaddr; ++ return icp_adf_iommu_map(*iova, phaddr, size); ++} ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return icp_adf_iommu_unmap(iova, size); ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return icp_adf_iommu_get_remapping_size(size); ++} ++#elif defined(ICP_OSAL_IOMMU) ++int osalIOMMUMap(uint64_t iova, uint64_t phaddr, size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ void *phaddr = (void *)virt_to_phys(vaddr); ++ *iova = phaddr; ++ return osalIOMMUMap((uintptr_t)*iova, phaddr, size); ++} ++ ++int osalIOMMUUnmap(uint64_t iova, size_t size); ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return osalIOMMUUnmap((uintptr_t)iova, size); ++} ++uint64_t osalIOMMUVirtToPhys(uint64_t iova); ++static inline uint64_t icp_iommu_virt_to_phys(void *iova) ++{ ++ return osalIOMMUVirtToPhys((uintptr_t)iova); ++} ++size_t osalIOMMUgetRemappingSize(size_t size); ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return osalIOMMUgetRemappingSize(size); ++} ++#elif defined(ICP_QDM_IOMMU) ++int qdm_iommu_map(void **iova, void *vaddr, size_t size); ++int qdm_iommu_unmap(void *iova, size_t size); ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++ return qdm_iommu_map(iova, vaddr, size); ++} ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return qdm_iommu_unmap(iova, size); ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); ++} ++#else ++#define ICP_IOMMU_DISABLED ++static inline int icp_iommu_map(void **iova, void *vaddr, size_t size) ++{ ++#ifdef __FreeBSD__ ++ *iova = (void *)(uintptr_t)vtophys(vaddr); ++#else ++ *iova = (void *)(uintptr_t)virt_to_phys(vaddr); ++#endif ++ return 0; ++} ++ ++static inline int icp_iommu_unmap(void *iova, size_t size) ++{ ++ return 0; ++} ++static inline size_t icp_iommu_get_remapping_size(size_t size) ++{ ++ return (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1); ++} ++#endif ++#endif ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/include/qdm.h +@@ -0,0 +1,61 @@ ++/* ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * Copyright(c) 2016 Intel Corporation. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * Contact Information: ++ * ++ * qat-linux@intel.com ++ * ++ * BSD LICENSE ++ * Copyright(c) 2016 Intel Corporation. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef __QDM_H__ ++#define __QDM_H__ ++#include ++ ++struct device; ++ ++int qdm_init(void); ++void qdm_exit(void); ++int qdm_attach_device(struct device *dev); ++int qdm_detach_device(struct device *dev); ++int qdm_iommu_map(dma_addr_t *iova, void *vaddr, size_t size); ++int qdm_iommu_unmap(dma_addr_t iova, size_t size); ++ ++#endif /* __QDM_H__ */ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_drv.c +@@ -0,0 +1,1590 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++ ++/** ++ * ++ * @file qae_mem_drv.c ++ * ++ * @brief Kernel-space support for user-space contiguous memory allocation ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qae_mem_utils.h" ++ ++#define DEV_MEM_NAME "usdm_drv" ++#define MODULE_NAME "USDM" ++#define DEV_MEM_MAJOR 0 ++#define DEV_MEM_MAX_MINOR 1 ++#define DEV_MEM_BASE_MINOR 0 ++#define QAE_LOCAL_ENSURE(c, str, ret) \ ++ if (!(c)) { \ ++ mm_err("%s in file %s, ret = %d\n", \ ++ str, __FILE__, ret); \ ++ return ret; } ++ ++#define FREE(ptr) kfree(ptr) ++#define IS_PAGE_ALIGNED(x) (PAGE_ALIGN((uintptr_t) (x)) == (uintptr_t) (x)) ++ ++/** ++****************************************************************************** ++* @ingroup max_mem_numa ++* maximum amount of memory allocated in kernel space ++* @description ++* This is a command line parameter that defines the maximum ++* amount of memory allocated by the driver in kernel space. ++* Measured in kilobytes. ++*****************************************************************************/ ++static uint32_t max_mem_numa = 0; ++/** ++****************************************************************************** ++* @ingroup mem_allocated ++* amount of memory currently allocated in kernel space ++* @description ++* This variable holds the overall ++* amount of memory allocated by the driver in kernel space. ++* Measured in bytes. ++*****************************************************************************/ ++static size_t mem_allocated = 0; ++/** ++****************************************************************************** ++* @ingroup max_huge_pages ++* total number of huge pages currently reserved ++* @description ++* This variable holds the total number of ++* huge pages reserved by the memory driver. ++* Measured in number of huge pages. ++*****************************************************************************/ ++static uint max_huge_pages = 0; ++/** ++****************************************************************************** ++* @ingroup max_huge_pages_per_process ++* number of huge pages could be allocated ++* for each user space process ++* @description ++* This variable holds the number of ++* huge pages allocated by each process. ++* Measured in number of huge pages. ++*****************************************************************************/ ++static uint max_huge_pages_per_process = 0; ++ ++ ++module_param(max_mem_numa, uint, S_IRUGO); ++MODULE_PARM_DESC(max_mem_numa, ++ "Maximum number of allocatable memory in 1k units"); ++ ++module_param(max_huge_pages, uint, S_IRUGO); ++MODULE_PARM_DESC(max_huge_pages, ++ "Maximum number of huge pages enabled for the module"); ++ ++module_param(max_huge_pages_per_process, uint, S_IRUGO); ++MODULE_PARM_DESC(max_huge_pages_per_process, ++ "Maximum number of huge pages enabled for each process"); ++ ++/* Version 0.7.1: ++ * - Slab caching in user space introduced; ++ * - Slab hash introduced for fast searching; ++ * - Performance optimizations; ++ * - Adding huge pages support. ++ */ ++static const char VERSION_STRING[]="Version 0.7.1"; ++ ++static DEFINE_MUTEX(dev_mem_lock); ++static user_mem_dev_t *mem_dev_numa = NULL; ++ ++/*directory entry structure for debug root directory and debug file*/ ++static struct dentry *qae_dbg_root_dir = NULL; ++static struct dentry *qae_dbg_slabs_file = NULL; ++ ++typedef struct chr_drv_info_s ++{ ++ unsigned major; ++ unsigned min_minor; ++ unsigned max_minor; ++ char *name; ++ struct cdev drv_cdev; ++ struct class *drv_class; ++ struct device *drv_class_dev; ++ unsigned num_devices; ++ unsigned unregistered; ++} chr_drv_info_t; ++ ++typedef struct { ++ kdev_mem_info_t *head; ++ kdev_mem_info_t *tail; ++} slab_list_t; ++/* Kernel space hash for fast slab searching */ ++static slab_list_t g_slab_list[PAGE_SIZE] = {{0}}; ++ ++extern int handle_other_ioctls(uint32_t cmd); ++/****************************************************************************** ++ * debug: /sys/kernel/debug/qae_mem_dbg directory ++ * qae_mem_slabs file ++ * cat qae_mem_slabs shows the allocated slabs for each process with the ++ * physical and virtual start address ++ * echo "d processid virt_addr" > qae_mem_slabs ++ * echo "d processid phys_addr" > qae_mem_slabs ++ * write dump command to debug file, the next cat qae_mem_slabs command ++ * shows the 256 byte from address in hex and ascii format ++ * echo "c processid slabid" > qae_mem_slabs ++ * write dump command to debug file, the next cat qae_mem_slabs command ++ * shows the 32 x 64 allocation bit map for small buffers allocations ++ ******************************************************************************/ ++ ++/***************************************************************************** ++ memory mgt code begin ++*****************************************************************************/ ++ ++static inline uint64_t get_key(const uint64_t phys) ++{ ++ /* Use bits 20-31 of a physical address as a hash key. ++ * It provides a good distribution for 1Mb/2Mb slabs ++ * and a moderate distribution for 128Kb/256Kb/512Kb slabs. ++ */ ++ return (phys >> 20) & ~PAGE_MASK; ++} ++ ++static inline void add_slab_to_hash(kdev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ ADD_ELEMENT_TO_HEAD_LIST(slab, g_slab_list[key].head, ++ g_slab_list[key].tail, _kernel_hash); ++} ++ ++static inline void del_slab_from_hash(kdev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ REMOVE_ELEMENT_FROM_LIST(slab, g_slab_list[key].head, ++ g_slab_list[key].tail, _kernel_hash); ++} ++ ++static inline kdev_mem_info_t *find_slab(const uint64_t phy_addr) ++{ ++ const size_t key = get_key(phy_addr); ++ kdev_mem_info_t *slab = g_slab_list[key].head; ++ ++ while (slab) ++ { ++ if (phy_addr == slab->phy_addr) ++ return slab; ++ slab = slab->pNext_kernel_hash; ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Find memory information ++ */ ++static kdev_mem_info_t* ++userMemGetInfo(struct file* fp, uint64_t id) ++{ ++ user_proc_mem_list_t* list = NULL; ++ if(!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__ ); ++ return NULL; ++ } ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if(!list) ++ { ++ mm_info("%s:%d empty list\n",__func__,__LINE__); ++ return NULL; ++ } ++ return find_slab(id); ++} ++/* ++ * Allocate numa memory ++ */ ++static dev_mem_info_t * ++userMemAlloc(struct file* fp, size_t size, ++ int node, int large_memory) ++{ ++ block_ctrl_t *block_ctrl = NULL; ++ dev_mem_info_t *mem_info = NULL; ++ kdev_mem_info_t *kmem = NULL; ++ user_proc_mem_list_t *list = NULL; ++ void *phy_addr = NULL; ++ size_t totalInKBytes = 0; ++ ++ if(!size || !fp) ++ { ++ mm_err("%s:%d Invalid parameter value [%zu] %p\n", ++ __func__, __LINE__, size, fp); ++ return NULL; ++ } ++ ++ if(node != NUMA_NO_NODE) ++ { ++ /* node 0.. (MAX_NUMNODES-1) */ ++ if(node >= 0 && node < MAX_NUMNODES) ++ { ++ if(!node_online(node)) ++ { ++ mm_err("%s:%d Requested node %d is not online. " ++ "Using node 0 as default\n", ++ __func__, __LINE__,node); ++ node = 0; ++ } ++ } ++ else ++ { ++ /*greater than MAX_NUMNODES */ ++ mm_err("%s:%d Requested node %d not present. " ++ "Using node 0 as default\n", ++ __func__, __LINE__,node); ++ node = 0; ++ } ++ } ++ ++ /* ++ * Find the process allocation list ++ */ ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if (!list) ++ { ++ mm_err("%s:%d User process memory list is NULL \n",__func__,__LINE__); ++ return NULL; ++ } ++ ++ size = icp_iommu_get_remapping_size(size); ++ totalInKBytes = DIV_ROUND_UP(mem_allocated + size, QAE_KBYTE); ++ ++ /* for request > 2M mem_info control block allocated separately */ ++ if(large_memory) ++ { ++ /*one page is used for block control information*/ ++ const uint32_t pageSizeInKb = PAGE_SIZE / QAE_KBYTE; ++ if ( max_mem_numa && max_mem_numa < (totalInKBytes + pageSizeInKb)) ++ { ++ mm_err(KERN_ERR "%s:%d Maximum NUMA allocation of %u kB reached " ++ "currently allocated %zu bytes requested %zu bytes\n", ++ __func__,__LINE__,max_mem_numa, ++ mem_allocated , (size_t)(size + PAGE_SIZE) ); ++ return NULL; ++ } ++ mem_info = (dev_mem_info_t*) get_zeroed_page(GFP_KERNEL); ++ if ( !mem_info ) ++ { ++ mm_err("%s:%d Unable to allocate control block\n", ++ __func__,__LINE__); ++ return NULL; ++ } ++ kmem = kmalloc (sizeof(kdev_mem_info_t), GFP_KERNEL); ++ if ( !kmem ) ++ { ++ mm_err("%s:%d Unable to allocate Kernel control block\n", ++ __func__,__LINE__); ++ free_page((unsigned long) mem_info); ++ return NULL; ++ } ++ /* kmalloc is faster than kzalloc */ ++ kmem->kmalloc_ptr = kmalloc_node(size, GFP_KERNEL, node); ++ if (!kmem->kmalloc_ptr || !IS_PAGE_ALIGNED(kmem->kmalloc_ptr)) ++ { ++ mm_err("%s:%d Unable to allocate memory slab size %zu" ++ " or wrong alignment: %p\n", ++ __func__, __LINE__, size, kmem->kmalloc_ptr); ++ FREE(kmem->kmalloc_ptr); ++ FREE(kmem); ++ free_page((unsigned long) mem_info); ++ return NULL; ++ } ++ /* Initialize the huge page control */ ++ kmem->huge_mem_ctrl = mem_info; ++ /* Update slab size */ ++ kmem->size = size; ++ /* Update allocated size */ ++ mem_allocated += (size + PAGE_SIZE); ++ } ++ else ++ { ++ if ( max_mem_numa && max_mem_numa < totalInKBytes ) ++ { ++ mm_err(KERN_ERR "%s:%d Maximum NUMA allocation of %u kB reached" ++ " currently allocated %zu bytes requested %zu bytes\n", ++ __func__, __LINE__, max_mem_numa, ++ mem_allocated, size); ++ return NULL; ++ } ++ block_ctrl = kmalloc_node(size, GFP_KERNEL, node); ++ if (!block_ctrl || !IS_PAGE_ALIGNED(block_ctrl)) ++ { ++ mm_err("%s:%d Unable to allocate memory slab" ++ " or wrong alignment: %p\n", ++ __func__, __LINE__, block_ctrl); ++ FREE(block_ctrl); ++ return NULL; ++ } ++ ++ kmem = kmalloc (sizeof(kdev_mem_info_t), GFP_KERNEL); ++ if ( !kmem ) ++ { ++ mm_err("%s:%d Unable to allocate Kernel control block\n", ++ __func__,__LINE__); ++ FREE(block_ctrl); ++ return NULL; ++ } ++ ++ /* It is faster to alloc a slab and memset it later vs. kZalloc_node. */ ++ memset(block_ctrl, 0, sizeof(block_ctrl_t)); ++ mem_info = &block_ctrl->mem_info; ++ kmem->kmalloc_ptr = block_ctrl; ++ /* Huge page control block not applicable here for small slabs. */ ++ kmem->huge_mem_ctrl = NULL; ++ /* Update slab size */ ++ kmem->size = size; ++ /* Update allocated size */ ++ mem_allocated += size; ++ } ++ mem_info->nodeId = node; ++ mem_info->size = size; ++ mem_info->type = large_memory; ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_map(&phy_addr, kmem->kmalloc_ptr, mem_info->size); ++#else ++ if (icp_iommu_map(&phy_addr, kmem->kmalloc_ptr, mem_info->size)) ++ { ++ mm_err("%s:%d iommu map failed\n",__func__,__LINE__); ++ if( LARGE == mem_info->type ) ++ { ++ free_page((unsigned long) mem_info); ++ mem_allocated -= PAGE_SIZE; ++ } ++ /* For small block size, kmalloc_ptr points to block_ctrl */ ++ FREE(kmem->kmalloc_ptr); ++ FREE(kmem); ++ mem_allocated -= size; ++ return NULL; ++ } ++#endif ++ mem_info->phy_addr = (uintptr_t) phy_addr; ++ kmem->phy_addr = (uintptr_t) phy_addr; ++ list->allocs_nr++; ++ ADD_ELEMENT_TO_END_LIST(kmem, list->head, list->tail, _kernel); ++ add_slab_to_hash(kmem); ++ ++ return mem_info; ++} ++/* ++ * Free slab ++ */ ++static void ++free_slab(user_proc_mem_list_t *list, kdev_mem_info_t *slab, ++ const int cleanup) ++{ ++ void *ptr = slab->kmalloc_ptr; ++ const size_t size = slab->size; ++ ++ icp_iommu_unmap((void *) (uintptr_t) slab->phy_addr, size); ++ REMOVE_ELEMENT_FROM_LIST(slab, list->head, list->tail, _kernel); ++ ++ del_slab_from_hash(slab); ++ ++ /* If we are dealing with huge pages, then huge_mem_ctrl is not NULL ++ * and the slab can be freed. ++ */ ++ if(slab->huge_mem_ctrl) ++ { ++ free_page((unsigned long) slab->huge_mem_ctrl); ++ mem_allocated -= PAGE_SIZE; ++ } ++ ++ if (cleanup) ++ { ++ /* Cleanup released memory. */ ++ memset(ptr, 0, size); ++ } ++ FREE(ptr); ++ ++ /* Destroy the slab as it is no longer needed */ ++ FREE(slab); ++ ++ mem_allocated -= size; ++ list->allocs_nr -= 1; ++} ++/* ++ * Free memory ++ */ ++static int ++userMemFree(struct file* fp, uint64_t id) ++{ ++ user_proc_mem_list_t* list = NULL; ++ kdev_mem_info_t *kmem = NULL; ++ ++ if (!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__); ++ return -EIO; ++ } ++ list = (user_proc_mem_list_t *)fp->private_data; ++ if(!list) ++ { ++ mm_warning("%s:%d No slab to free\n",__func__,__LINE__); ++ return -EIO; ++ } ++ kmem = find_slab(id); ++ if (kmem) ++ { ++ /* Free memory slab, no cleanup. */ ++ free_slab(list, kmem, 0); ++ return 0; ++ } ++ mm_warning("%s:%d Could not find slab with id: %llu \n", ++ __func__,__LINE__,id); ++ return -EIO; ++} ++/* ++ * Clean all memory for a process ++ */ ++static int ++userMemFreeSlabs(struct file* fp) ++{ ++ kdev_mem_info_t* kmem = NULL, *next = NULL; ++ user_proc_mem_list_t* list = NULL; ++ ++ if (!fp) ++ { ++ mm_err("%s:%d Invalid file pointer\n",__func__,__LINE__); ++ return -EIO; ++ } ++ list = (user_proc_mem_list_t*)fp->private_data; ++ if(!list) ++ { ++ mm_warning("%s:%d No slab to free\n",__func__,__LINE__); ++ return -EIO; ++ } ++ max_huge_pages += list->hugepages_nr; ++#ifdef ICP_DEBUG ++ mm_info("[FREE] pid: %u return number of pages: %llu total number: %u\n", ++ current->pid, ++ list->hugepages_nr, ++ max_huge_pages); ++#endif ++ list->hugepages_nr = 0; ++ kmem = list->head; ++ while(kmem) ++ { ++#ifdef ICP_DEBUG ++ mm_warning("%s:%d Potential memory leak, Process Id %d " ++ "Virtual address %p " ++ "Physical address %px has allocated block\n", ++ __func__,__LINE__, ++ list->pid, ++ kmem->kmalloc_ptr, ++ (void*)kmem->phy_addr); ++#endif ++ next = kmem->pNext_kernel; ++ /* Free and cleanup memory slab. */ ++ free_slab(list, kmem, 1); ++ kmem = next; ++ } ++ return 0; ++} ++ ++/***************************************************************************** ++ memory mgt code end ++*****************************************************************************/ ++ ++static int ++dev_mem_alloc(struct file* fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ dev_mem_info_t* mem_info = NULL; ++ dev_mem_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data \n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, ++ (dev_mem_info_t *)arg, ++ sizeof(dev_mem_info_t)); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ mem_info = userMemAlloc(fp, user_mem_info.size, ++ (int) user_mem_info.nodeId, ++ user_mem_info.type); ++ if (!mem_info) ++ { ++ mm_err("%s:%d userMemAlloc failed\n",__func__,__LINE__); ++ return -ENOMEM; ++ } ++ ret = copy_to_user((dev_mem_info_t *)arg, ++ mem_info, ++ sizeof(dev_mem_info_t)); ++ if (unlikely(ret)) ++ { ++ (void) userMemFree(fp, user_mem_info.phy_addr); ++ mm_err("%s:%d copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ++dev_mem_free(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ dev_mem_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, ++ (dev_mem_info_t *)arg, ++ sizeof(dev_mem_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_mem_free: copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return userMemFree(fp, user_mem_info.phy_addr); ++} ++ ++static int ++dev_release_pid(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ return userMemFreeSlabs(fp); ++} ++static int ++dev_get_user_page(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret; ++ struct page *page; ++ int errno = 0; ++ user_page_info_t user_mem_info = {0}; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ ret = copy_from_user(&user_mem_info, (user_page_info_t *)arg, ++ sizeof(user_page_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_get_user_page: copy_from_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ ++ errno = get_user_pages_fast( ++ (unsigned long)user_mem_info.virt_addr, 1, 1, &page); ++ if ( errno != 1 ) ++ { ++ user_mem_info.phy_addr = 0x00; ++ mm_err("%s:%d dev_get_user_page: get_user_pages_fast failed, ret=%d\n", ++ __func__,__LINE__,errno); ++ return -EIO; ++ } ++ else ++ { ++ if (PageHuge(page)) ++ { ++ user_mem_info.phy_addr = page_to_phys(page); ++ } ++ else ++ { ++ user_mem_info.phy_addr = 0x00; ++ } ++ ++ } ++ put_page(page); ++ ++ ret = copy_to_user( (user_page_info_t *)arg, &user_mem_info, ++ sizeof(user_page_info_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_get_user_page: copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ return 0; ++} ++ ++static int ++dev_num_hp_get(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ unsigned long ret = 0; ++ uint actual_num_hugepages = 0; ++ ++ if( fp == NULL ) ++ { ++ mm_err("%s:%d Invalid file descriptor\n",__func__,__LINE__); ++ return -EIO; ++ } ++ if( fp->private_data == NULL) ++ { ++ mm_err("%s:%d Invalid file private data\n",__func__,__LINE__); ++ return -EIO; ++ } ++ actual_num_hugepages = min(max_huge_pages, max_huge_pages_per_process); ++ ret = copy_to_user((uint32_t *)arg, ++ &actual_num_hugepages, ++ sizeof(uint32_t)); ++ if (ret) ++ { ++ mm_err("%s:%d dev_num_hp_get: copy_to_user failed, ret=%lu\n", ++ __func__,__LINE__,ret); ++ return -EIO; ++ } ++ max_huge_pages -= actual_num_hugepages; ++ ((user_proc_mem_list_t*)fp->private_data)->hugepages_nr = ++ actual_num_hugepages; ++#ifdef ICP_DEBUG ++ mm_info("[ALLOC] pid: %u max_huge_pages: %u actual_num_hugepages: %u\n", ++ current->pid, ++ max_huge_pages, ++ actual_num_hugepages); ++#endif ++ return 0; ++} ++ ++static long ++mem_ioctl(struct file *fp, uint32_t cmd, unsigned long arg) ++{ ++ int ret = 0; ++ switch(cmd) { ++ case DEV_MEM_IOC_MEMALLOC: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_mem_alloc(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (ret) ++ { ++ return -ENOMEM; ++ } ++ break; ++ ++ case DEV_MEM_IOC_MEMFREE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_mem_free(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_RELEASE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_release_pid(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_GET_NUM_HPT: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_num_hp_get(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ case DEV_MEM_IOC_GET_USER_PAGE: ++ mutex_lock(&dev_mem_lock); ++ ret = dev_get_user_page(fp, cmd, arg); ++ mutex_unlock(&dev_mem_lock); ++ if (unlikely(ret)) ++ { ++ return -EIO; ++ } ++ break; ++ ++ default: ++ ret = handle_other_ioctls(cmd); ++ return ret; ++ } ++ return 0; ++} ++ ++static int cmd_mmap_access(struct vm_area_struct *vma, ++ unsigned long addr, void *buf, int len, int write) ++{ ++ int size = vma->vm_end - addr; ++ unsigned long offs = addr - vma->vm_start; ++ unsigned long phy_addr = vma->vm_pgoff << PAGE_SHIFT; ++ void *virt_addr = phys_to_virt(phy_addr); ++ ++ len = min(len, size); ++ ++ if (write) ++ memcpy(virt_addr + offs, buf, len); ++ else ++ memcpy(buf, virt_addr + offs, len); ++ ++ return len; ++} ++ ++static struct vm_operations_struct cmd_mmap_operations = { ++ .access = cmd_mmap_access, ++}; ++ ++static int ++mem_mmap(struct file *fp, struct vm_area_struct *vma) ++{ ++ int ret = 0; ++ uint64_t id = 0; ++ unsigned long phys_kmalloc_area = 0; ++ kdev_mem_info_t *kmem = NULL; ++ unsigned long size = vma->vm_end - vma->vm_start; ++ id = vma->vm_pgoff << PAGE_SHIFT; ++ ++ mutex_lock(&dev_mem_lock); ++ kmem = userMemGetInfo(fp, id); ++ if (!kmem) ++ { ++ mutex_unlock(&dev_mem_lock); ++ mm_err("%s:%d cannot find meminfo\n",__func__,__LINE__); ++ return -ENOMEM; ++ } ++ ++ /* Ensure memory mapping does not exceed the allocated memory region */ ++ if (size > kmem->size) ++ { ++ mutex_unlock(&dev_mem_lock); ++ mm_err("%s:%d cannot map allocated memory region\n", ++ __func__, __LINE__); ++ return -ENOMEM; ++ } ++ ++ /* There is an agreement that mmap(PAGE_SIZE) means control block. */ ++ if (PAGE_SIZE == size) ++ { ++ phys_kmalloc_area = virt_to_phys(kmem->huge_mem_ctrl); ++ } ++ /* Any other size means memory block. */ ++ else ++ { ++ phys_kmalloc_area = virt_to_phys(kmem->kmalloc_ptr); ++ } ++ mutex_unlock(&dev_mem_lock); ++ ++ vma->vm_ops = &cmd_mmap_operations; ++ ret = remap_pfn_range(vma, ++ vma->vm_start, ++ phys_kmalloc_area >> PAGE_SHIFT, ++ size, ++ vma->vm_page_prot); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d remap_pfn_range failed, ret = %d\n", ++ __func__,__LINE__,ret); ++ } ++ return ret; ++} ++static int ++mem_open(struct inode *inp, struct file *fp) ++{ ++ user_proc_mem_list_t *list = NULL; ++ mutex_lock(&dev_mem_lock); ++ if (!fp->private_data) ++ { ++ list = kzalloc(sizeof(user_proc_mem_list_t), GFP_KERNEL); ++ if(!list) ++ { ++ mm_err("%s:%d memory allocation failed\n", ++ __func__,__LINE__); ++ mutex_unlock(&dev_mem_lock); ++ return -ENODEV; ++ } ++ fp->private_data = list; ++ ADD_ELEMENT_TO_END_LIST(list, mem_dev_numa->head, ++ mem_dev_numa->tail, ); ++ list->pid = current->tgid; ++ } ++ mutex_unlock(&dev_mem_lock); ++ return 0; ++} ++ ++static inline void remove_element(user_proc_mem_list_t * p) ++{ ++ if (NULL == p) ++ return; ++ if (NULL != p->pPrev) { ++ p->pPrev->pNext = p->pNext; ++ } ++ if (NULL != p->pNext) { ++ p->pNext->pPrev = p->pPrev; ++ } ++} ++ ++static int ++mem_release(struct inode *inp, struct file *fp) ++{ ++ user_proc_mem_list_t *list = NULL; ++ mutex_lock(&dev_mem_lock); ++ list=(user_proc_mem_list_t *)fp->private_data; ++ if( list ) ++ { ++ (void)userMemFreeSlabs(fp); ++ if (NULL != mem_dev_numa) ++ { ++ REMOVE_ELEMENT_FROM_LIST(list, ++ mem_dev_numa->head, mem_dev_numa->tail, ); ++ } ++ else ++ { ++ remove_element(list); ++ } ++ FREE(list); ++ fp->private_data=NULL; ++ } ++ mutex_unlock(&dev_mem_lock); ++ return 0; ++} ++ ++static struct file_operations mem_ops = { ++ owner:THIS_MODULE, ++ mmap:mem_mmap, ++ unlocked_ioctl:mem_ioctl, ++ compat_ioctl:mem_ioctl, ++ open:mem_open, ++ release:mem_release, ++}; ++ ++static chr_drv_info_t mem_drv_info = { ++ major:0, ++ min_minor:DEV_MEM_BASE_MINOR, ++ max_minor:DEV_MEM_MAX_MINOR, ++ name:DEV_MEM_NAME, ++}; ++ ++static int32_t ++chr_drv_create_class(chr_drv_info_t* drv_info) ++{ ++ QAE_LOCAL_ENSURE(drv_info, ++ "chr_drv_create_class(): Invalid parameter value ", ++ -EINVAL); ++ ++ drv_info->drv_class = class_create(THIS_MODULE, drv_info->name); ++ if (IS_ERR(drv_info->drv_class)) ++ { ++ mm_err("%s:%d class_create failed\n",__func__,__LINE__); ++ return -ENODEV; ++ } ++ return 0; ++} ++ ++static void ++chr_drv_destroy_class(chr_drv_info_t* drv_info) ++{ ++ if (NULL == drv_info) ++ { ++ mm_err("%s:%d Invalid parameter value\n",__func__,__LINE__); ++ return; ++ }; ++ class_destroy( drv_info->drv_class ); ++ drv_info->drv_class = NULL; ++ return; ++} ++ ++static inline void ++chr_drv_destroy_device(chr_drv_info_t *drv_info) ++{ ++ if (NULL == drv_info) ++ { ++ mm_err("%s:%d Invalid parameter value\n",__func__,__LINE__); ++ return; ++ } ++ if (NULL != drv_info->drv_class_dev) ++ { ++ device_destroy(drv_info->drv_class, MKDEV(drv_info->major, ++ DEV_MEM_BASE_MINOR)); ++ } ++ cdev_del(&(drv_info->drv_cdev)); ++ unregister_chrdev_region( MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ drv_info->max_minor); ++ return; ++} ++ ++static int ++chr_drv_create_device(chr_drv_info_t *drv_info) ++{ ++ int ret = 0; ++ dev_t devid = 0; ++ ++ QAE_LOCAL_ENSURE(drv_info, ++ "chr_drv_create_device(): Invalid parameter value ", ++ -ENODEV); ++ ret = alloc_chrdev_region(&devid, ++ drv_info->min_minor, ++ drv_info->max_minor, ++ drv_info->name); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d Unable to allocate chrdev region\n", ++ __func__,__LINE__); ++ return -ENOMEM; ++ } ++ drv_info->major = MAJOR(devid); ++ drv_info->drv_cdev.owner=THIS_MODULE; ++ cdev_init(&(drv_info->drv_cdev), &mem_ops); ++ ret = cdev_add(&(drv_info->drv_cdev), devid, drv_info->max_minor); ++ if (unlikely(ret)) ++ { ++ mm_err("%s:%d cdev add failed\n",__func__,__LINE__); ++ chr_drv_destroy_device(drv_info); ++ return -ENOENT; ++ } ++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) ++ drv_info->drv_class_dev = device_create(drv_info->drv_class, ++ NULL, MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ NULL, "%s", drv_info->name); ++#else ++ drv_info->drv_class_dev = device_create(drv_info->drv_class, ++ NULL, MKDEV(drv_info->major, DEV_MEM_BASE_MINOR), ++ drv_info->name); ++#endif ++ if( NULL == drv_info->drv_class_dev ) ++ { ++ mm_err("%s:%d device_create failed\n",__func__,__LINE__); ++ chr_drv_destroy_device(drv_info); ++ return -ENOMEM; ++ } ++ return 0; ++} ++ ++static int32_t register_mem_device_driver(void) ++{ ++ int ret = 0; ++ mutex_init(&dev_mem_lock); ++ mem_dev_numa = kzalloc(sizeof(user_mem_dev_t), GFP_KERNEL); ++ if(!mem_dev_numa) ++ { ++ mm_err("failed to allocate memory for numa mem device\n"); ++ return -ENOMEM; ++ } ++ ret = chr_drv_create_class(&mem_drv_info); ++ if(unlikely(ret)) ++ { ++ mm_err("failed to create device driver class\n"); ++ FREE(mem_dev_numa); ++ return -ENODEV; ++ } ++ ret = chr_drv_create_device(&mem_drv_info); ++ if(unlikely(ret)) ++ { ++ mm_err("failed to create mem numa device driver\n"); ++ chr_drv_destroy_class(&mem_drv_info); ++ FREE(mem_dev_numa); ++ return -ENODEV; ++ } ++ mem_drv_info.unregistered = 0; ++ return 0; ++} ++/* ++ * unregister the device driver ++ */ ++static void unregister_mem_device_driver(void) ++{ ++ if(!mem_drv_info.unregistered) ++ { ++ chr_drv_destroy_device(&mem_drv_info); ++ chr_drv_destroy_class(&mem_drv_info); ++ FREE(mem_dev_numa); ++ mem_dev_numa = NULL; ++ mem_drv_info.unregistered = 1; ++ } ++} ++ ++static inline char printable(char sym) ++{ ++ if (sym >= 0x20 && sym <= 0x7E) ++ /*check if printable ascii*/ ++ return sym; ++ else ++ /*else put out a dot*/ ++ return '.'; ++} ++ ++static char qae_dbg_ascii[128]; ++static char qae_dbg_command[128]; ++static char qae_dbg_slab_data[4096]; ++/*dumps memory data in 16 8 hex bytes and 8 ascii chars columns and 32 rows*/ ++static int ++dumpData(void *start, void *end) ++{ ++ int row = 0; ++ int col = 0; ++ char *src = start; ++ char *endaddr = end; ++ size_t offs = 0; ++ const int ROWS = 32; ++ const int COLUMNS = 8; ++ ++ for (row = 0; row < ROWS; ++row) ++ { ++ size_t ascii = 0; ++ ++ for (col = 0; col < COLUMNS; ++col) ++ { ++ if (src > endaddr) ++ { ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, " "); ++ ascii += scnprintf(qae_dbg_ascii + ascii, ++ sizeof(qae_dbg_ascii) - ascii, " "); ++ } ++ else ++ { ++ /*in the first 8 columns print bytes in hex with 2 nibbles*/ ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, "%02hhx ", *src); ++ /*in the last 8 columns print ascii char or dot*/ ++ ascii += scnprintf(qae_dbg_ascii + ascii, ++ sizeof(qae_dbg_ascii) - ascii, "%c ", printable(*src)); ++ src++; ++ } ++ } ++ offs += scnprintf(qae_dbg_slab_data + offs, ++ sizeof(qae_dbg_slab_data) - offs, "%.128s\n", qae_dbg_ascii); ++ if (src > endaddr) ++ return offs; ++ } ++ return offs; ++} ++/* ++ * findSlabsForPid - find the link list of slabs for a given pid ++ */ ++static kdev_mem_info_t* ++findSlabsForPid(const uint64_t pid) ++{ ++ if (mem_dev_numa) ++ { ++ user_proc_mem_list_t *list = mem_dev_numa->head; ++ while (list) ++ { ++ if (list->pid == pid ) ++ return list->head; ++ list=list->pNext; ++ } ++ } ++ return NULL; ++} ++/* ++ * execute dump command ++ * returns length of data in output buffer ++ */ ++static int ++execDump(kdev_mem_info_t* slab, const uintptr_t param, const uint64_t pid) ++{ ++ uintptr_t endaddr = 0; ++ uintptr_t startaddr = param; ++ uintptr_t offset = 0; ++ size_t len = 0; ++ ++ mm_info("Process dump command \n"); ++ /* traverse thru slabs */ ++ while (slab) ++ { ++ uintptr_t phy_addr = (uintptr_t) slab->phy_addr; ++ uintptr_t virt_addr = (uintptr_t) slab->kmalloc_ptr; ++ /*calculate virtual address end of slab*/ ++ endaddr = virt_addr + slab->size; ++ /*check if this slab was sought after by virtual address*/ ++ if (startaddr >= virt_addr && startaddr < endaddr) ++ { ++ offset = startaddr - virt_addr; ++ mm_info("Block found: " ++ "start %p block end %p dump addr %p offset %p\n", ++ (void *) virt_addr, (void *) endaddr, ++ (void *) startaddr, (void *) offset); ++ break; ++ } ++ /*calculate physical address end of slab*/ ++ endaddr = phy_addr + slab->size; ++ /*check if this slab was sought after by phy address*/ ++ if (startaddr >= phy_addr && startaddr < endaddr) ++ { ++ offset = startaddr - phy_addr; ++ mm_info("Block found (using phy_addr): " ++ "start %p block end %p dump addr %p offset %p\n", ++ (void *) phy_addr, (void *) endaddr, ++ (void *) startaddr, (void *) offset); ++ break; ++ } ++ /* take next slab if no hit */ ++ slab = slab->pNext_kernel; ++ } ++ /* log slab not found */ ++ if( !slab ) ++ { ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Slab not found PID %llu Address %p\n", ++ pid, (void *) startaddr); ++ } ++ else /*dump 256 byte of slab data */ ++ { ++ startaddr = (uintptr_t) slab + offset; ++ endaddr = (uintptr_t) slab + ++ slab->size - 1; ++ len = dumpData((void *) startaddr, (void *) endaddr); ++ } ++ return len; ++} ++/* ++ * execute dump control area command ++ * returns length of data in output buffer ++ */ ++static int32_t ++execDumpControl(kdev_mem_info_t* slab, const uintptr_t param, const uint64_t pid) ++{ ++ uint64_t id = param; ++ uintptr_t endaddr = 0; ++ size_t len = 0; ++ ++ /*traverse thru slabs search by slab id*/ ++ while(slab) ++ { ++ endaddr = slab->phy_addr + slab->size; ++ if (id >= slab->phy_addr && id < endaddr) ++ { ++ break; ++ } ++ slab = slab->pNext_kernel; ++ } ++ if( !slab ) /* log slab not found*/ ++ { ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Slab not found PID %llu slab ID %llu\n", pid, id); ++ } ++ else /*dump bitmap*/ ++ { ++ int row; ++ uint64_t bitmap_row,mask; ++ /* banner message */ ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Small buffer allocation bitmap \n Slab id %llu \n", id); ++ /* display 0/1 in bitmap positions throughout the bitmap */ ++ for ( row = 0; row < BITMAP_LEN; ++row ) ++ { ++ /* The slab does not contain any bitmap information anymore. ++ * We must now access with kmalloc_ptr */ ++ bitmap_row = ((block_ctrl_t*)slab->kmalloc_ptr)->bitmap[row]; ++ for ( mask = 1ULL<<(QWORD_WIDTH-1); mask; mask>>=1) ++ { ++ char bit = '0'; ++ if ( mask & bitmap_row ) ++ { ++ bit = '1'; ++ } ++ len += scnprintf(qae_dbg_slab_data + len, ++ sizeof(qae_dbg_slab_data) - len, "%c", bit); ++ } ++ len += scnprintf(qae_dbg_slab_data + len, ++ sizeof(qae_dbg_slab_data) - len, "\n"); ++ } ++ } ++ return len; ++} ++/* processCommand ++ * performs the command found in the command buffer ++ * returns the number of characters the debug ++ * buffer has after command was executed ++ */ ++static int ++processCommand(void) ++{ ++ char *arg = NULL; ++ char *cmd = NULL; ++ char command = '\0'; /*command char c/d*/ ++ uint64_t param = 0; /*command parameter*/ ++ uint64_t pid = 0; /*process id*/ ++ kdev_mem_info_t* slab = NULL; /*slab the info is required for*/ ++ size_t len = 0; /*length of string in output buffer*/ ++ ++ command = qae_dbg_command[0]; ++ if ('\0' == command) /*check if there is a command*/ ++ { ++ return 0; ++ } ++ /* Search for a first numeric argument after the command itself. */ ++ cmd = strpbrk(qae_dbg_command, "0123456789"); ++ arg = strsep(&cmd, " "); ++ if (NULL != arg) { ++ int status = kstrtoll(arg, 0, &pid); ++ pid *= (status == 0); ++ ++ /* Find a next argument. */ ++ arg = strsep(&cmd, " "); ++ if (NULL != arg) ++ { ++ status = kstrtoll(arg, 0, ¶m); ++ param *= (status == 0); ++ } ++ } ++ mm_info("%s:%d " ++ "Command %c Param %llu %llu Buffer %s Arg %s\n", ++ __func__, __LINE__, command, pid, param, qae_dbg_command, arg); ++ /* Destroy the original command. */ ++ qae_dbg_command[0] = '\0'; ++ ++ switch (command) ++ { ++ case 'd': ++ slab = findSlabsForPid(pid); /* find slab for process id*/ ++ if(!slab) ++ { ++ mm_info("%s:%d " ++ "Could not find slab for process id: %llu\n", ++ __func__,__LINE__,pid); ++ return 0; ++ } ++ /*dump memory content*/ ++ len = execDump(slab,param,pid); ++ break; ++ case 'c': ++ slab = findSlabsForPid(pid); /* find slab for process id*/ ++ if(!slab) ++ { ++ mm_info("%s:%d " ++ "Could not find slab for process id: %llu\n", ++ __func__,__LINE__,pid); ++ return 0; ++ } ++ /* control block data (bitmap) */ ++ len = execDumpControl(slab,param,pid); ++ break; ++ case 't': ++ /* print total allocated NUMA memory */ ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Total allocated NUMA memory: %zu bytes\n", ++ mem_allocated); ++ break; ++ default: ++ len = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Invalid command %c\n", command); ++ break; ++ } ++ return len; ++} ++/* print info about a slab in debug buffer ++ * return number of byte in buffer ++ * 0 return value will end the file read operation ++ * each time this function is called one slab data ++ * is entered in the debug buffer ++ * process and slab ptrs are saved in static variables ++ * to traverse the linked list by file read until a 0 ++ * return value is received. ++ */ ++static int ++getMemInfo(user_proc_mem_list_t** pmem_list) ++{ ++ /*memory info for slab in memory list*/ ++ static kdev_mem_info_t* mem_info; ++ /*memory list element of current process*/ ++ user_proc_mem_list_t* mem_list = *pmem_list; ++ int length = 0; ++ /*initialise list of processes that allocated slabs*/ ++ if (!mem_info && !mem_list ) ++ { ++ mem_list = mem_dev_numa->head; ++ /*return if list is empty*/ ++ if ( !mem_list) ++ return 0; ++ mem_info = mem_list->head; ++ } ++ /* iterate through all processes in the list*/ ++ while(mem_list) ++ { ++ /*check if there is a valid slab entry*/ ++ if(mem_info) ++ { ++ length = scnprintf(qae_dbg_slab_data, sizeof(qae_dbg_slab_data), ++ "Pid %d, Slab Id %llu \n" ++ "Virtual address %p, Physical Address %llx, Size %lld\n", ++ mem_list->pid, mem_info->phy_addr, mem_info->kmalloc_ptr, ++ mem_info->phy_addr, mem_info->size); ++ /*advance slab pointer for next call*/ ++ mem_info = mem_info->pNext_kernel; ++ /*send slab info into read buffer*/ ++ break; ++ } ++ else ++ { ++ /* null slab ptr in list of previous process ++ * get next process from list*/ ++ mem_list = mem_list->pNext; ++ /*get first slab from next list element*/ ++ if(mem_list) ++ mem_info = mem_list->head; ++ } ++ } ++ /* if at the end of process list chain*/ ++ if(!mem_list) ++ { ++ mem_list = mem_dev_numa->head; ++ mem_info = NULL; ++ } ++ /* save current process in list in a static for next call*/ ++ *pmem_list = mem_list; ++ return length; ++} ++/* ++*qae_mem_update_slab_data ++* updates data in debug buffer depending on last command ++* open - non-null if called from debug file open routine ++* otherwise 0 ++*/ ++static int ++qae_mem_update_slab_data(int open) ++{ ++ /* memory list of current process*/ ++ static user_proc_mem_list_t* mem_list; ++ static int count; /*number of chars in debug buffer*/ ++ if( !mem_dev_numa ) ++ return 0; ++ /* if file just opened initialise; make sure ++ * list of slabs are generated from the top ++ * if qae_dbg_command buffer is empty */ ++ if(open) ++ { ++ mem_list = NULL; ++ count = 0; ++ return 0; ++ } ++ /* last time a buffer with chars were sent in response to read operation ++ return 0 now to complete read operation.*/ ++ if(count) ++ { ++ count = 0; ++ return 0; ++ } ++ /* process command and report to read op if there is any result*/ ++ count = processCommand(); ++ if(count) ++ return count; ++ /*get next slab info into debug data buffer*/ ++ /* when 0 is returned it marks the end of buffer list*/ ++ /* and will end the file read operation as well*/ ++ return getMemInfo(&mem_list); ++} ++/*read function for debug file ++ returns number of bytes read ++ read operation completes when 0 is returned here*/ ++static ssize_t ++qae_mem_slabs_data_read(struct file* filp, char __user *buffer, ++ size_t count, loff_t * pos) ++{ ++ /*update data in debug buffer*/ ++ int data_len = qae_mem_update_slab_data(false); ++ /*check length and position */ ++ if( 0 == data_len || *pos >= data_len ) ++ return 0; ++ /* Ensure the addition of (*pos + count) does not overflow */ ++ if ((*pos + count) > ULLONG_MAX) ++ return 0; ++ if( *pos + count > data_len ) ++ count = data_len - *pos; ++ /*copy from kernel buffer to user*/ ++ if( copy_to_user(buffer ,qae_dbg_slab_data + *pos, ++ (unsigned)count)) ++ return -EFAULT; ++ return count; ++} ++/*write function for write operation of the debug file*/ ++static ssize_t ++qae_mem_slabs_data_write (struct file *filp, ++ const char __user *buffer, ++ size_t count, loff_t *pos) ++{ ++ /*write command to qae_dbg_command buffer ++ *next read on debug file will parse the command string ++ *and execute the requested command ++ *if command buffer empty the next read ++ *lists the allocated slabs */ ++ /* check count vs size of command buffer*/ ++ if (count >= sizeof(qae_dbg_command) ) ++ { ++ return -EFAULT; ++ } ++ /* copy command string from user buffer*/ ++ if ( copy_from_user(qae_dbg_command, buffer, count) ) ++ { ++ return -EFAULT; ++ } ++ /*terminating 0*/ ++ qae_dbg_command[count] = '\0'; ++ return count; ++} ++/*called when debug file is opened ++ used for initialisation */ ++static int ++qae_mem_slabs_data_open(struct inode *inode, struct file* filep) ++{ ++ qae_mem_update_slab_data(1); ++ return 0; ++} ++static struct file_operations qae_mem_slabs_file_fops = { ++ .owner = THIS_MODULE, ++ .open = qae_mem_slabs_data_open, ++ .read = qae_mem_slabs_data_read, ++ .write = qae_mem_slabs_data_write ++}; ++/* ++ * Initialisation function to insmod device driver ++ */ ++static inline void ++qae_debug_init(void) ++{ ++ if ( ( qae_dbg_root_dir = debugfs_create_dir("qae_mem_dbg", NULL) ) ++ == ERR_PTR(-ENODEV) || ++ ( qae_dbg_slabs_file = debugfs_create_file("qae_mem_slabs", 0666, ++ qae_dbg_root_dir, NULL, ++ &qae_mem_slabs_file_fops) ) == ERR_PTR(-ENODEV) ) ++ { ++ mm_warning( ++ "Debug FS not initialised, debug info not available\n"); ++ } ++} ++ ++static int ++qae_mem_init( void ) ++{ ++ mm_info("Loading %s Module %s ...\n", MODULE_NAME, VERSION_STRING); ++ mm_info("IOCTLs: %lx, %lx, %lx, %lx\n", ++ (unsigned long)DEV_MEM_IOC_MEMALLOC, ++ (unsigned long)DEV_MEM_IOC_MEMFREE, ++ (unsigned long)DEV_MEM_IOC_RELEASE, ++ (unsigned long)DEV_MEM_IOC_GET_NUM_HPT); ++ if(register_mem_device_driver()) ++ { ++ mm_err("Error loading %s Module\n", MODULE_NAME); ++ return -1; ++ } ++ qae_debug_init(); ++ return 0; ++} ++/* ++ * tear down function to rmmod device driver ++ */ ++STATIC void ++qae_mem_exit( void ) ++{ ++ mm_info("Unloading %s Module %s...\n", MODULE_NAME, VERSION_STRING); ++ unregister_mem_device_driver(); ++ if( NULL != qae_dbg_root_dir ) ++ { ++ debugfs_remove_recursive(qae_dbg_root_dir); ++ qae_dbg_root_dir = NULL; ++ } ++} ++module_init(qae_mem_init); ++module_exit(qae_mem_exit); ++ ++ ++MODULE_AUTHOR("Intel Corporation"); ++MODULE_LICENSE("Dual BSD/GPL"); ++MODULE_DESCRIPTION("User Space DMA-able Memory Driver"); ++ ++ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_drv_utils.c +@@ -0,0 +1,82 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++ * @file qae_mem_drv_utils.c ++ * ++ * This file handles ioctls from user space to kernel space for quick assist API ++ * ++ *****************************************************************************/ ++ ++#include ++#include ++#include ++ ++#include "qae_mem_utils.h" ++ ++int handle_other_ioctls(uint32_t cmd) ++{ ++ mm_err("Invalid IOCTL command specified(0x%x)\n", cmd); ++ return -EINVAL; ++} ++ +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qae_mem_utils.c +@@ -0,0 +1,277 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++***************************************************************************** ++ * @file qae_mem_utils.c ++ * ++ * This file provides linux kernel memory allocation for quick assist API ++ * ++ *****************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "qae_mem.h" ++#include "qae_mem_utils.h" ++ ++#define IS_VMALLOC_ADDR(addr) (((uintptr_t)(addr) >= VMALLOC_START) && \ ++ ((uintptr_t)(addr) < VMALLOC_END)) ++ ++/** ++****************************************************************************** ++* @ingroup max_mem_numa ++* maximum amount of memory allocated in kernel space ++* @description ++* This is a command line parameter that defines the maximum ++* amount of memory allocated by the driver in kernel space. ++* Measured in kilobytes. ++*****************************************************************************/ ++static uint32_t max_mem_numa = 0; ++/** ++****************************************************************************** ++* @ingroup mem_allocated ++* amount of memory currently allocated in kernel space ++* @description ++* This variable holds the overall ++* amount of memory allocated by the driver in kernel space. ++* Measured in bytes. ++*****************************************************************************/ ++static size_t mem_allocated = 0; ++module_param(max_mem_numa, uint, S_IRUGO); ++MODULE_PARM_DESC(max_mem_numa,"Maximum number of allocatable memory in 1k units"); ++ ++static uint32_t numaAllocations_g = 0; ++static uint32_t normalAllocations_g = 0; ++ ++/*Defining Max Size limit to be used, to allocate using kmalloc as 4MB */ ++static const int QAE_MEM_SIZE_LIMIT = 1024 * 4096; ++ ++/************************************** ++ * Memory functions ++ *************************************/ ++void* qaeMemAlloc (size_t memsize) ++{ ++ if(memsize > QAE_MEM_SIZE_LIMIT) ++ { ++ return ( vmalloc(memsize) ); ++ } ++ normalAllocations_g++; ++ return (kmalloc (memsize, GFP_KERNEL)); ++} ++ ++void* qaeMemAllocNUMA(size_t size, int node, size_t alignment) ++{ ++ void* ptr = NULL; ++ void* phys_ptr = NULL; ++ void* pRet = NULL; ++ size_t alignment_offset = 0; ++ qae_mem_alloc_info_t memInfo = {0}; ++ size_t totalInKBytes = (mem_allocated + size)/QAE_KBYTE; ++ ++ if( (mem_allocated + size) % QAE_KBYTE ) ++ { ++ totalInKBytes += 1; ++ } ++ ++ if( max_mem_numa && max_mem_numa < totalInKBytes) ++ { ++ mm_err("%s:%d Maximum NUMA allocation of %u kB reached " ++ "currently allocated %zu bytes requested %zu bytes\n", ++ __func__,__LINE__,max_mem_numa,mem_allocated, size); ++ return NULL; ++ } ++ ++ if(!size || alignment < 1) ++ { ++ mm_err("%s:%d Either size or alignment is zero - size = %zu, " ++ "alignment = %zu \n",__func__,__LINE__,size,alignment); ++ return NULL; ++ } ++ /*alignment should be 1,2,4,8....*/ ++ if(alignment & (alignment-1)) ++ { ++ mm_err("%s:%d Expecting alignment of a power of "\ ++ "two but did not get one\n",__func__,__LINE__); ++ return NULL; ++ } ++ /*add the alignment and the struct size to the buffer size*/ ++ memInfo.mSize = icp_iommu_get_remapping_size(size + alignment + ++ sizeof(qae_mem_alloc_info_t)); ++ if(memInfo.mSize > QAE_MEM_SIZE_LIMIT) ++ { ++ mm_err("%s:%d Total size needed for this " \ ++ "set of size and alignment (%zu) exceeds the OS " \ ++ "limit %d\n", __func__,__LINE__,memInfo.mSize,QAE_MEM_SIZE_LIMIT); ++ return NULL; ++ } ++ /*allocate contigous memory*/ ++ ptr = kmalloc_node (memInfo.mSize, GFP_KERNEL, node); ++ if(!ptr) ++ { ++ mm_err("%s:%d failed to allocate memory\n",__func__,__LINE__); ++ return NULL; ++ } ++ /*store the base address into the struct*/ ++ memInfo.mAllocMemPtr = ptr; ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_map(&phys_ptr, ptr, memInfo.mSize); ++#else ++ if (icp_iommu_map(&phys_ptr, ptr, memInfo.mSize)) ++ { ++ mm_err("%s:%d failed to iommu map\n",__func__,__LINE__); ++ kfree(ptr); ++ return NULL; ++ } ++#endif ++ /*add the size of the struct to the return pointer*/ ++ pRet = (char *)memInfo.mAllocMemPtr + sizeof(qae_mem_alloc_info_t); ++ /*compute the offset from the alignement*/ ++ alignment_offset = (uintptr_t)pRet % alignment; ++ /*in order to obtain the pointer to the buffer add the alignment and ++ subtract the offset, now we have the return pointer aligned*/ ++ pRet = (char*)pRet + (alignment - alignment_offset); ++ /*copy the struct immediately before the buffer pointer*/ ++ memcpy((void*)((char*)pRet - sizeof(qae_mem_alloc_info_t)), ++ (void*)(&memInfo), ++ sizeof(qae_mem_alloc_info_t)); ++ /*increment the NUMA allocations counter*/ ++ numaAllocations_g++; ++ mem_allocated += memInfo.mSize; ++ return pRet; ++} ++ ++void qaeMemFreeNUMA (void** ptr) ++{ ++ qae_mem_alloc_info_t *memInfo = NULL; ++ uint64_t phy_addr = 0; ++ ++ if(!ptr || !(*ptr) ) ++ { ++ mm_err("%s:%d Pointer to be freed cannot be NULL\n", ++ __func__,__LINE__); ++ return; ++ } ++ memInfo = (qae_mem_alloc_info_t *)((int8_t *)*ptr - ++ sizeof(qae_mem_alloc_info_t)); ++ ++ if (memInfo->mSize == 0 || memInfo->mAllocMemPtr == NULL) ++ { ++ mm_err("%s:%d Detected the corrupted data: memory leak!! \n", ++ __func__,__LINE__); ++ mm_err("%s:%d Size: %zu, memPtr: %p\n", ++ __func__,__LINE__,memInfo->mSize, memInfo->mAllocMemPtr); ++ return; ++ } ++ phy_addr = virt_to_phys(memInfo->mAllocMemPtr); ++#ifdef ICP_IOMMU_DISABLED ++ icp_iommu_unmap((void*)(uintptr_t) phy_addr, memInfo->mSize); ++#else ++ if (icp_iommu_unmap((void*)(uintptr_t) phy_addr, memInfo->mSize)) ++ { ++ mm_warning("%s:%d failed to iommu unmap\n",__func__,__LINE__); ++ } ++#endif ++ kfree (memInfo->mAllocMemPtr); ++ numaAllocations_g--; ++ if ( mem_allocated > memInfo->mSize ) ++ { ++ mem_allocated -= memInfo->mSize; ++ } ++ else ++ { ++ mem_allocated = 0; ++ } ++ *ptr = NULL; ++} ++ ++void qaeMemFree (void **ptr) ++{ ++ if(!ptr || !(*ptr) ) ++ { ++ mm_err("%s:%d Pointer to be freed cannot be NULL\n",__func__,__LINE__); ++ return; ++ } ++ if(IS_VMALLOC_ADDR(*ptr)) ++ { ++ vfree(*ptr); ++ return; ++ } ++ kfree (*ptr); ++ normalAllocations_g--; ++ *ptr = NULL; ++} ++ ++uint64_t qaeVirtToPhysNUMA(void* ptr) ++{ ++ if (!ptr) ++ { ++ mm_err("%s:%d Input parameter cannot be NULL \n", ++ __func__,__LINE__); ++ return 0; ++ } ++ return (uint64_t)(uintptr_t)virt_to_phys(ptr); ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/kernel_space/qdm.c +@@ -0,0 +1,187 @@ ++/* ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * Copyright(c) 2016 Intel Corporation. ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * Contact Information: ++ * ++ * qat-linux@intel.com ++ * ++ * BSD LICENSE ++ * Copyright(c) 2016 Intel Corporation. ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++#ifndef LINUX_VERSION_CODE ++#include ++#else ++#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) ++#endif ++ ++#include ++#include ++#include ++#include "qdm.h" ++ ++static struct iommu_domain *domain; ++ ++/** ++ * qdm_attach_device() - Attach a device to the QAT IOMMU domain ++ * @dev: Device to be attached ++ * ++ * Function attaches the device to the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_attach_device(struct device *dev) ++{ ++ if (!domain) ++ return 0; ++ ++ if (!dev) { ++ pr_err("QDM: Invalid device\n"); ++ return -ENODEV; ++ } ++ ++ return iommu_attach_device(domain, dev); ++} ++ ++/** ++ * qdm_detach_device() - Detach a device from the QAT IOMMU domain ++ * @dev: Device to be detached ++ * ++ * Function detaches the device from the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_detach_device(struct device *dev) ++{ ++ if (!domain) ++ return 0; ++ ++ if (!dev) { ++ pr_err("QDM: Invalid device\n"); ++ return -ENODEV; ++ } ++ ++ iommu_detach_device(domain, dev); ++ return 0; ++} ++ ++/** ++ * qdm_iommu_map() - Map a block of memory to the QAT IOMMU domain ++ * @iova: Device virtual address ++ * @vaddr: Kernel virtual address ++ * @size: Size (in bytes) of the memory block. ++ * Must be a multiple of PAGE_SIZE ++ * ++ * Function maps a block of memory to the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_iommu_map(dma_addr_t *iova, void *vaddr, size_t size) ++{ ++ phys_addr_t paddr = (phys_addr_t) virt_to_phys(vaddr); ++ *iova = (dma_addr_t) paddr; ++ ++ if (!domain) ++ return 0; ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34) ++ return iommu_map_range(domain, *iova, paddr, size, ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#elif LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,45) && \ ++ LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ return iommu_map(domain, *iova, paddr, get_order(size), ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#else ++ return iommu_map(domain, *iova, paddr, size, ++ IOMMU_READ|IOMMU_WRITE|IOMMU_CACHE); ++#endif ++} ++EXPORT_SYMBOL_GPL(qdm_iommu_map); ++ ++/** ++ * qdm_iommu_unmap() - Unmap a block of memory from the QAT IOMMU domain ++ * @iova: Device virtual address ++ * @size: Size (in bytes) of the memory block ++ * Must be the same size as mapped. ++ * ++ * Function unmaps a block of memory from the QDM IOMMU domain. ++ * ++ * Return: 0 on success, error code otherwise. ++ */ ++int qdm_iommu_unmap(dma_addr_t iova, size_t size) ++{ ++ if (!domain) ++ return 0; ++ ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34) ++ iommu_unmap_range(domain, (unsigned long)iova, size); ++#elif LINUX_VERSION_CODE <= KERNEL_VERSION(3,2,45) && \ ++ LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35) ++ iommu_unmap(domain, (unsigned long)iova, get_order(size)); ++#else ++ iommu_unmap(domain, (unsigned long)iova, size); ++#endif ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(qdm_iommu_unmap); ++ ++int __init qdm_init(void) ++{ ++ if (!iommu_present(&pci_bus_type)) ++ return 0; ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0) ++ domain = iommu_domain_alloc(); ++#else ++ domain = iommu_domain_alloc(&pci_bus_type); ++#endif ++ if (!domain) { ++ pr_err("QDM: Failed to allocate a domain\n"); ++ return -1; ++ } ++ return 0; ++} ++ ++void __exit qdm_exit(void) ++{ ++ if (domain) ++ iommu_domain_free(domain); ++ domain = NULL; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_hugepage_utils.c +@@ -0,0 +1,288 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_hugepage_utils.c ++ * ++ * This file provides for utilities for Linux/FreeBSD user space memory ++ * allocation with huge page enabled. ++ * ++ ***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifndef __FreeBSD__ ++#include "qae_page_table.h" ++#endif ++#include "qae_mem_hugepage_utils.h" ++#include "qae_mem_user_utils.h" ++ ++#define HUGEPAGE_FILE_DIR "/dev/hugepages/usdm.XXXXXX" ++#define HUGEPAGE_FILE_LEN (sizeof(HUGEPAGE_FILE_DIR)) ++ ++#ifndef __FreeBSD__ ++static bool g_hugepages_enabled = false; ++#else ++static const bool g_hugepages_enabled = false; ++#endif ++ ++static size_t g_num_hugepages = 0; ++ ++#ifndef __FreeBSD__ /* FreeBSD only uses init_hugepages, hugepage_enabled */ ++/* ++ * Get physical address of mapped hugepage virtual address in the current ++ * process. ++ */ ++API_LOCAL ++uint64_t hugepage_virt2phy(const int fd, const void *virtaddr) ++{ ++ int ret = 0; ++ user_page_info_t user_pages = {0}; ++ ++ user_pages.virt_addr = (uintptr_t)virtaddr; ++ ret = mem_ioctl(fd, DEV_MEM_IOC_GET_USER_PAGE, &user_pages); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for get physical addr failed, " ++ "ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ ret = -EIO; ++ } ++ ++ return user_pages.phy_addr; ++} ++ ++API_LOCAL ++void *hugepage_mmap_phy_addr(const size_t len) ++{ ++ void *addr = NULL; ++ int ret = 0; ++ int hpg_fd; ++ char hpg_fname[HUGEPAGE_FILE_LEN]; ++ ++ /* ++ * for every mapped huge page there will be a separate file descriptor ++ * created from a temporary file, we should NOT close fd explicitly, it ++ * will be reclaimed by the OS when the process gets terminated, and ++ * meanwhile the huge page binding to the fd will be released, this could ++ * guarantee the memory cleanup order between user buffers and ETR. ++ */ ++ snprintf(hpg_fname, sizeof(HUGEPAGE_FILE_DIR), "%s", HUGEPAGE_FILE_DIR); ++ hpg_fd = qae_mkstemp(hpg_fname); ++ ++ if (hpg_fd < 0) ++ { ++ CMD_ERROR("%s:%d mkstemp(%s) for hpg_fd failed with errno: %d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ return NULL; ++ } ++ ++ unlink(hpg_fname); ++ ++ addr = qae_mmap(NULL, ++ len, ++ PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, ++ hpg_fd, ++ 0); ++ ++ if (MAP_FAILED == addr) ++ { ++ CMD_ERROR("%s:%d qae_mmap(%s) for hpg_fd failed with errno:%d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ close(hpg_fd); ++ return NULL; ++ } ++ ++ ret = qae_madvise(addr, len, MADV_DONTFORK); ++ if (0 != ret) ++ { ++ munmap(addr, len); ++ CMD_ERROR("%s:%d qae_madvise(%s) for hpg_fd failed with errno:%d\n", ++ __func__, ++ __LINE__, ++ hpg_fname, ++ errno); ++ close(hpg_fd); ++ return NULL; ++ } ++ ++ ((dev_mem_info_t *)addr)->hpg_fd = hpg_fd; ++ return addr; ++} ++ ++API_LOCAL ++dev_mem_info_t *hugepage_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ if (!g_num_hugepages) ++ { ++ CMD_ERROR("%s:%d mmap: exceeded max huge pages allocations for this " ++ "process.\n", ++ __func__, ++ __LINE__); ++ return NULL; ++ } ++ slab = hugepage_mmap_phy_addr(size); ++ if (!slab) ++ { ++ CMD_ERROR("%s:%d mmap on huge page memory allocation failed\n", ++ __func__, ++ __LINE__); ++ return NULL; ++ } ++ slab->nodeId = node; ++ slab->size = size; ++ slab->type = type; ++ slab->virt_addr = slab; ++ slab->phy_addr = hugepage_virt2phy(fd, slab); ++ if (!slab->phy_addr) ++ { ++ CMD_ERROR("%s:%d virt2phy on huge page memory allocation failed\n", ++ __func__, ++ __LINE__); ++ close(slab->hpg_fd); ++ munmap(slab, size); ++ return NULL; ++ } ++ g_num_hugepages--; ++ ++ return slab; ++} ++ ++API_LOCAL ++void hugepage_free_slab(const dev_mem_info_t *memInfo) ++{ ++ g_num_hugepages++; ++ ++ close(memInfo->hpg_fd); ++} ++ ++#endif /* !__FreeBSD__ */ ++ ++API_LOCAL ++int init_hugepages(const int fd) ++{ ++ int ret = 0; ++#if (QAE_NUM_PAGES_PER_ALLOC == 512) ++#ifndef __FreeBSD__ ++ ret = mem_ioctl(fd, DEV_MEM_IOC_GET_NUM_HPT, &g_num_hugepages); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for checking number of huge page failed, " ++ "ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ g_num_hugepages = 0; ++ ret = -EIO; ++ } ++ if (g_num_hugepages > 0) ++ { ++ set_free_page_table_fptr(free_page_table_hpg); ++ set_loadaddr_fptr(load_addr_hpg); ++ set_loadkey_fptr(load_key_hpg); ++ ++ g_hugepages_enabled = true; ++ } ++ else ++ { ++ set_free_page_table_fptr(free_page_table); ++ set_loadaddr_fptr(load_addr); ++ set_loadkey_fptr(load_key); ++ ++ g_hugepages_enabled = false; ++ } ++#endif /* !__FreeBSD__ */ ++#else ++ if (fd < 0) ++ return -EIO; ++#endif ++ return ret; ++} ++ ++API_LOCAL ++int hugepage_enabled() ++{ ++ return g_hugepages_enabled; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_hugepage_utils.h +@@ -0,0 +1,91 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_hugepage_utils.h ++ * ++ * This file provides API for utilities of Linux/FreeBSD user space memory ++ * allocation with huge page enabled. ++ * ++ ***************************************************************************/ ++#ifndef QAE_MEM_HUGEPAGE_UTILS_H ++#define QAE_MEM_HUGEPAGE_UTILS_H ++#ifndef __FreeBSD__ ++#include "qae_mem_utils.h" ++ ++uint64_t hugepage_virt2phy(const int fd, const void *virtaddr); ++ ++void *hugepage_mmap_phy_addr(const size_t len); ++ ++dev_mem_info_t *hugepage_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type); ++ ++void hugepage_free_slab(const dev_mem_info_t *memInfo); ++#endif /* !__FreeBSD__ */ ++ ++int init_hugepages(const int fd); ++ ++int hugepage_enabled(); ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_user_utils.h +@@ -0,0 +1,108 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_user_utils.h ++ * ++ * This file provides for API of Linux user space memory allocation ++ * ++ ***************************************************************************/ ++ ++#ifndef QAE_MEM_USER_UTILS_H ++#define QAE_MEM_USER_UTILS_H ++ ++#ifndef SKIP_BUILTIN_FUNC ++#define unlikely(x) __builtin_expect((x), 0) ++#else ++#define unlikely(x) (0 == (x)) ++#endif ++ ++#if __GNUC__ >= 4 ++#define API_PUBLIC __attribute__((visibility("default"))) ++#define API_LOCAL __attribute__((visibility("hidden"))) ++#else ++#define API_PUBLIC ++#define API_LOCAL ++#endif ++ ++#ifdef ICP_DEBUG ++static inline void CMD_DEBUG(const char *format, ...) ++{ ++ va_list args; ++ va_start(args, format); ++ vfprintf(stdout, format, args); ++ va_end(args); ++} ++#else ++#define CMD_DEBUG(...) ++#endif ++ ++static inline void CMD_ERROR(const char *format, ...) ++{ ++ va_list args; ++ va_start(args, format); ++ vfprintf(stderr, format, args); ++ va_end(args); ++} ++ ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_mem_utils.c +@@ -0,0 +1,1331 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ **************************************************************************** ++ * @file qae_mem_utils.c ++ * ++ * This file provides for Linux user space memory allocation. It uses ++ * a driver that allocates the memory in kernel memory space (to ensure ++ * physically contiguous memory) and maps it to ++ * user space for use by the quick assist sample code ++ * ++ ***************************************************************************/ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifndef ICP_WITHOUT_THREAD ++#include ++#endif ++#include ++#include ++#include ++#include "qae_mem.h" ++#include "qae_mem_utils.h" ++#include "qae_mem_user_utils.h" ++#include "qae_page_table.h" ++#include "qae_mem_hugepage_utils.h" ++ ++STATIC int fd = -1; ++ ++/************************************************************************** ++ macro ++**************************************************************************/ ++ ++#define QAE_MEM "/dev/usdm_drv" ++ ++/************************************************************************** ++ static variable ++**************************************************************************/ ++ ++/* Current cached memory size. */ ++static size_t g_cache_size = 0; ++/* Maximum cached memory size, 8 Mb by default */ ++static size_t g_max_cache = 0x800000; ++/* The maximum number we allow to search for available size */ ++static size_t g_max_lookup_num = 10; ++/* User space page table for fast virtual to physical address translation */ ++static page_table_t g_page_table = {{{0}}}; ++ ++typedef struct ++{ ++ dev_mem_info_t *head; ++ dev_mem_info_t *tail; ++} slab_list_t; ++/* User space hash for fast slab searching */ ++static slab_list_t g_slab_list[PAGE_SIZE] = {{0}}; ++ ++static int g_strict_node = 1; ++ ++#ifndef ICP_WITHOUT_THREAD ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++#endif ++ ++static dev_mem_info_t *pUserCacheHead = NULL; ++static dev_mem_info_t *pUserCacheTail = NULL; ++static dev_mem_info_t *pUserMemListHead = NULL; ++static dev_mem_info_t *pUserMemListTail = NULL; ++static dev_mem_info_t *pUserLargeMemListHead = NULL; ++static dev_mem_info_t *pUserLargeMemListTail = NULL; ++ ++ ++static free_page_table_fptr_t free_page_table_fptr = free_page_table; ++static load_addr_fptr_t load_addr_fptr = load_addr; ++static load_key_fptr_t load_key_fptr = load_key; ++ ++/************************************************************************** ++ function ++**************************************************************************/ ++#ifndef __FreeBSD__ ++API_LOCAL ++void set_free_page_table_fptr(free_page_table_fptr_t fp) ++{ ++ free_page_table_fptr = fp; ++} ++ ++API_LOCAL ++void set_loadaddr_fptr(load_addr_fptr_t fp) ++{ ++ load_addr_fptr = fp; ++} ++ ++API_LOCAL ++void set_loadkey_fptr(load_key_fptr_t fp) ++{ ++ load_key_fptr = fp; ++} ++#endif /* __FreeBSD__ */ ++ ++static inline size_t div_round_up(const size_t n, const size_t d) ++{ ++ return (n + d - 1) / d; ++} ++ ++static inline void add_slab_to_hash(dev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ ADD_ELEMENT_TO_HEAD_LIST( ++ slab, g_slab_list[key].head, g_slab_list[key].tail, _user_hash); ++} ++static inline void del_slab_from_hash(dev_mem_info_t *slab) ++{ ++ const size_t key = get_key(slab->phy_addr); ++ ++ REMOVE_ELEMENT_FROM_LIST( ++ slab, g_slab_list[key].head, g_slab_list[key].tail, _user_hash); ++} ++ ++static inline dev_mem_info_t *find_slab_in_hash(void *virt_addr) ++{ ++ const size_t key = load_key_fptr(&g_page_table, virt_addr); ++ dev_mem_info_t *slab = g_slab_list[key].head; ++ ++ while (slab) ++ { ++ uintptr_t offs = (uintptr_t)virt_addr - (uintptr_t)slab->virt_addr; ++ if (offs < slab->size) ++ return slab; ++ slab = slab->pNext_user_hash; ++ } ++ ++ return NULL; ++} ++ ++/* mem_ctzll function ++ * input: a 64-bit bitmap window ++ * output: number of contiguous 0s from least significant bit position ++ * __GNUC__ predefined macro and __builtin_ctz() are supported by Intel C ++ */ ++static inline int32_t mem_ctzll(uint64_t bitmap_window) ++{ ++ if (bitmap_window) ++ { ++#ifdef __GNUC__ ++ return __builtin_ctzll(bitmap_window); ++#else ++#error "Undefined built-in function" ++#endif ++ } ++ return QWORD_WIDTH; ++} ++ ++/* bitmap_read function ++ * reads a 64-bit window from a BITMAP_LENx64-bit bitmap ++ * starting from window_pos (0 <-> BITMAP_LENx64 -1) ++ * map points to the BITMAP_LENx64 bit map area ++ * returns the 64-bit window from the BITMAP_LENx64 bitmap. ++ * Each bit represents a 1k block in the 2 Meg buffer ++ */ ++ ++static uint64_t bitmap_read(uint64_t *map, size_t window_pos) ++{ ++ uint64_t quad_word_window = 0ULL; ++ uint64_t next_quad_word = 0ULL; ++ size_t quad_word_pos = 0; ++ size_t bit_pos = 0; ++ ++ quad_word_pos = window_pos / QWORD_WIDTH; ++ ++ if (quad_word_pos >= BITMAP_LEN) ++ { ++ return QWORD_ALL_ONE; ++ } ++ bit_pos = window_pos % QWORD_WIDTH; ++ ++ quad_word_window = map[quad_word_pos]; ++ ++ if (0 == bit_pos) ++ { ++ return quad_word_window; ++ } ++ ++ /* it is safe to read the next quad word because ++ * there is always a barrier at the end */ ++ next_quad_word = map[quad_word_pos + 1]; ++ ++ quad_word_window >>= bit_pos; ++ next_quad_word <<= QWORD_WIDTH - bit_pos; ++ quad_word_window |= next_quad_word; ++ ++ return quad_word_window; ++} ++ ++static const uint64_t __bitmask[65] = { ++ 0x0000000000000000ULL, 0x0000000000000001ULL, 0x0000000000000003ULL, ++ 0x0000000000000007ULL, 0x000000000000000fULL, 0x000000000000001fULL, ++ 0x000000000000003fULL, 0x000000000000007fULL, 0x00000000000000ffULL, ++ 0x00000000000001ffULL, 0x00000000000003ffULL, 0x00000000000007ffULL, ++ 0x0000000000000fffULL, 0x0000000000001fffULL, 0x0000000000003fffULL, ++ 0x0000000000007fffULL, 0x000000000000ffffULL, 0x000000000001ffffULL, ++ 0x000000000003ffffULL, 0x000000000007ffffULL, 0x00000000000fffffULL, ++ 0x00000000001fffffULL, 0x00000000003fffffULL, 0x00000000007fffffULL, ++ 0x0000000000ffffffULL, 0x0000000001ffffffULL, 0x0000000003ffffffULL, ++ 0x0000000007ffffffULL, 0x000000000fffffffULL, 0x000000001fffffffULL, ++ 0x000000003fffffffULL, 0x000000007fffffffULL, 0x00000000ffffffffULL, ++ 0x00000001ffffffffULL, 0x00000003ffffffffULL, 0x00000007ffffffffULL, ++ 0x0000000fffffffffULL, 0x0000001fffffffffULL, 0x0000003fffffffffULL, ++ 0x0000007fffffffffULL, 0x000000ffffffffffULL, 0x000001ffffffffffULL, ++ 0x000003ffffffffffULL, 0x000007ffffffffffULL, 0x00000fffffffffffULL, ++ 0x00001fffffffffffULL, 0x00003fffffffffffULL, 0x00007fffffffffffULL, ++ 0x0000ffffffffffffULL, 0x0001ffffffffffffULL, 0x0003ffffffffffffULL, ++ 0x0007ffffffffffffULL, 0x000fffffffffffffULL, 0x001fffffffffffffULL, ++ 0x003fffffffffffffULL, 0x007fffffffffffffULL, 0x00ffffffffffffffULL, ++ 0x01ffffffffffffffULL, 0x03ffffffffffffffULL, 0x07ffffffffffffffULL, ++ 0x0fffffffffffffffULL, 0x1fffffffffffffffULL, 0x3fffffffffffffffULL, ++ 0x7fffffffffffffffULL, 0xffffffffffffffffULL, ++}; ++ ++/* clear_bitmap function ++ * clear the BITMAP_LENx64-bit bitmap from pos ++ * for len length ++ * input : map - pointer to the bitmap ++ * pos - bit position ++ * len - number of contiguous bits ++ */ ++static inline void clear_bitmap(uint64_t *bitmap, ++ const size_t index, ++ size_t len) ++{ ++ size_t qword = index / QWORD_WIDTH; ++ const size_t offset = index % QWORD_WIDTH; ++ size_t num; ++ ++ if (offset > 0) ++ { ++ const size_t width = MIN(len, QWORD_WIDTH - offset); ++ const uint64_t mask = __bitmask[width] << offset; ++ ++ /* Clear required bits */ ++ bitmap[qword] &= ~mask; ++ ++ len -= width; ++ qword += 1; ++ } ++ ++ num = len / QWORD_WIDTH; ++ len %= QWORD_WIDTH; ++ ++ while (num--) ++ { ++ bitmap[qword++] = 0; ++ } ++ ++ /* Clear remaining bits */ ++ bitmap[qword] &= ~__bitmask[len]; ++} ++ ++/* set_bitmap function ++ * set the BITMAP_LENx64-bit bitmap from pos ++ * for len length ++ * input : map - pointer to the bitmap ++ * pos - bit position ++ * len - number of contiguous bits ++ */ ++static inline void set_bitmap(uint64_t *bitmap, const size_t index, size_t len) ++{ ++ size_t qword = index / QWORD_WIDTH; ++ const size_t offset = index % QWORD_WIDTH; ++ size_t num; ++ ++ if (offset > 0) ++ { ++ const size_t width = MIN(len, QWORD_WIDTH - offset); ++ const uint64_t mask = __bitmask[width] << offset; ++ ++ /* Set required bits */ ++ bitmap[qword] |= mask; ++ ++ len -= width; ++ qword += 1; ++ } ++ ++ num = len / QWORD_WIDTH; ++ len %= QWORD_WIDTH; ++ ++ while (num--) ++ { ++ bitmap[qword++] = ~0ULL; ++ } ++ ++ /* Set remaining bits */ ++ bitmap[qword] |= __bitmask[len]; ++} ++ ++/* mem_alloc function ++ * mem_alloc allocates memory with min. size = UNIT_SIZE ++ * block_ctrl points to a block_ctrl_t structure with virtual address ++ * size is the requested number of bytes ++ * minimum allocation size is UNIT_SIZE ++ * returns a pointer to the newly allocated block ++ * input: block_ctrl - pointer to the memory control block ++ * size - size requested in bytes ++ * output: pointer to the allocated area ++ */ ++static void *mem_alloc(block_ctrl_t *block_ctrl, size_t size, size_t align) ++{ ++ uint64_t *bitmap = NULL; ++ size_t window_pos = 0; ++ void *retval = NULL; ++ size_t blocks_found = 0; ++ uint64_t bitmap_window = 0ULL; ++ size_t blocks_required = 0ULL; ++ size_t first_block = 0; ++ size_t width = 0; ++ size_t width_ones = 0; ++ ++ if (NULL == block_ctrl || 0 == size) ++ { ++ CMD_ERROR(" %s:%d invalid control block or size provided " ++ "block_ctrl = %p and size = %d \n", ++ __func__, ++ __LINE__, ++ block_ctrl, ++ size); ++ return retval; ++ } ++ ++ bitmap = block_ctrl->bitmap; ++ ++ blocks_required = div_round_up(size, UNIT_SIZE); ++ ++ window_pos = 0; ++ first_block = window_pos; ++ ++ do ++ { ++ /* read 64-bit bitmap window from window_pos (0-BITMAP_LEN*64) */ ++ bitmap_window = bitmap_read(bitmap, window_pos); ++ /* find number of contiguous 0s from right */ ++ width = mem_ctzll(bitmap_window); ++ ++ /* increment number of blocks found with number of contig. 0s ++ in bitmap window */ ++ blocks_found += width; ++ /* check if a fit is found */ ++ if (blocks_found >= blocks_required) ++ { ++ /* calculate return address from virtual address and ++ first block number */ ++ retval = (uint8_t *)(block_ctrl) + first_block * UNIT_SIZE; ++ if (first_block + blocks_required > BITMAP_LEN * QWORD_WIDTH) ++ { ++ CMD_ERROR("%s:%d Allocation error - Required blocks exceeds " ++ "bitmap window. Block index = %d, Blocks required" ++ " = %zu and Bitmap window = %d \n", ++ __func__, ++ __LINE__, ++ first_block, ++ blocks_required, ++ (BITMAP_LEN * QWORD_WIDTH)); ++ return NULL; ++ } ++ /* save length in the reserved area right after the bitmap */ ++ block_ctrl->sizes[first_block] = (uint16_t)blocks_required; ++ /* set bit maps from bit position (0<->BITMAP_LEN*64 -1) = ++ * first_block(0<->BITMAP_LEN*64-1) ++ * with blocks_required length in bitmap ++ */ ++ set_bitmap(bitmap, first_block, blocks_required); ++ break; ++ } ++ else ++ { ++ /* did not find fit check if bitmap_window has at least a 1*/ ++ if (bitmap_window) ++ { ++ /* bit field of 0s not contiguous, clear blocks_found adjust ++ * first_block and window_pos find width of contiguous 1 bits ++ * and move window position will read next 64-bit wide window ++ * from bitmap ++ */ ++ bitmap_window >>= (width + 1); ++ width_ones = mem_ctzll(~bitmap_window); ++ blocks_found = 0; ++ window_pos += width + 1 + width_ones; ++ if (align && window_pos % align) ++ { ++ window_pos += align - window_pos % align; ++ } ++ first_block = window_pos; ++ } ++ else ++ { ++ /* bit field of 0s is contiguous, but fit not found yet ++ * move window_pos an search more 0s */ ++ window_pos += width; ++ } ++ } ++ } while (window_pos < BITMAP_LEN * QWORD_WIDTH); ++ return retval; ++} ++/* ++ * deallocates previously allocated blocks ++ * block_ctrl is a pointer to block_ctrl_t structure ++ * block is a result from a previous mem_alloc call ++ */ ++static void mem_free(block_ctrl_t *block_ctrl, void *block) ++{ ++ size_t first_block = 0; ++ uint32_t length = 0; ++ uint8_t *start_of_block = block; ++ uint64_t *bitmap = NULL; ++ ++ if (NULL == block_ctrl || NULL == block) ++ { ++ CMD_ERROR("%s:%d One of the parameters is NULL. block_ctrl = %p " ++ "block = %p\n", ++ __func__, ++ __LINE__, ++ block_ctrl, ++ block); ++ return; ++ } ++ ++ if ((uintptr_t)block % UNIT_SIZE) ++ { ++ CMD_ERROR("%s:%d Block address(%p) must be multiple of Unit size(%d)\n", ++ __func__, ++ __LINE__, ++ block, ++ UNIT_SIZE); ++ return; ++ } ++ ++ bitmap = block_ctrl->bitmap; ++ ++ /* find start of block in block numbers using the address of start of ++ * buffer and block retrieve first_block and length of block from integer ++ * at the start of block ++ */ ++ first_block = ++ (uintptr_t)(start_of_block - (uint8_t *)(block_ctrl)) / UNIT_SIZE; ++ ++ length = block_ctrl->sizes[first_block]; ++ ++ if (length + first_block > BITMAP_LEN * QWORD_WIDTH) ++ { ++ CMD_ERROR("%s:%d Invalid block address provided - " ++ "block length exceeds bitmap window. block index = %d " ++ "and block length: %d\n", ++ __func__, ++ __LINE__, ++ first_block, ++ length); ++ return; ++ } ++ /* clear bitmap from bitmap position (0<->BITMAP_LEN*64 - 1) for length*/ ++ clear_bitmap(bitmap, first_block, length); ++ ++#ifndef ICP_DISABLE_SECURE_MEM_FREE ++ qae_memzero_explicit(block, length * UNIT_SIZE); ++#endif ++} ++ ++static dev_mem_info_t *userMemLookupBySize(size_t size, ++ int node, ++ void **block, ++ const size_t align) ++{ ++ dev_mem_info_t *pCurr = NULL; ++ size_t link_num = 0; ++ ++ for (pCurr = pUserMemListHead; pCurr != NULL; pCurr = pCurr->pNext_user) ++ { ++ if (g_strict_node && (pCurr->nodeId != node)) ++ { ++ continue; ++ } ++ *block = mem_alloc((block_ctrl_t *)pCurr, size, align); ++ if (NULL != *block) ++ { ++ return pCurr; ++ } ++ /* Prevent from visiting whole chain, because after the first ++ * several node, the chance to get one is very small. ++ * Another consideration is to prevent new allocation from old ++ * link, so that the old link could be released ++ */ ++ link_num++; ++ if (link_num >= g_max_lookup_num) ++ { ++ break; ++ } ++ } ++ return NULL; ++} ++ ++static inline void *init_slab_and_alloc(block_ctrl_t *slab, ++ const size_t size, ++ const size_t phys_align_unit) ++{ ++ const size_t last = slab->mem_info.size / CHUNK_SIZE; ++ dev_mem_info_t *p_ctrl_blk = &slab->mem_info; ++ const size_t reserved = div_round_up(sizeof(block_ctrl_t), UNIT_SIZE); ++ void *virt_addr = NULL; ++ ++ /* initialise the bitmap to 1 for reserved blocks */ ++ slab->bitmap[0] = (1ULL << reserved) - 1; ++ /* make a barrier to stop search at the end of the bitmap */ ++ slab->bitmap[last] = QWORD_ALL_ONE; ++ ++ virt_addr = mem_alloc(slab, size, phys_align_unit); ++ if (NULL != virt_addr) ++ { ++ ADD_ELEMENT_TO_HEAD_LIST( ++ p_ctrl_blk, pUserMemListHead, pUserMemListTail, _user); ++ } ++ return virt_addr; ++} ++ ++static inline int push_slab(dev_mem_info_t *slab) ++{ ++ if (g_cache_size + slab->size <= g_max_cache) ++ { ++ g_cache_size += slab->size; ++ ADD_ELEMENT_TO_HEAD_LIST(slab, pUserCacheHead, pUserCacheTail, _user); ++ return 0; ++ } ++ return -ENOMEM; ++} ++ ++static inline dev_mem_info_t *pop_slab(const int node) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ for (slab = pUserCacheHead; slab != NULL; slab = slab->pNext_user) ++ { ++ if (node != NUMA_ANY_NODE) ++ if (g_strict_node && (node != slab->nodeId)) ++ continue; ++ ++ g_cache_size -= slab->size; ++ REMOVE_ELEMENT_FROM_LIST(slab, pUserCacheHead, pUserCacheTail, _user); ++ return slab; ++ } ++ return NULL; ++} ++ ++static inline void free_slab(const int fd, dev_mem_info_t *slab) ++{ ++ dev_mem_info_t memInfo; ++ int ret = 0; ++ ++ del_slab_from_hash(slab); ++ ++ memcpy(&memInfo, slab, sizeof(dev_mem_info_t)); ++ /* Need to disconnect from orignal chain */ ++ ret = qae_munmap(memInfo.virt_addr, memInfo.size); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d munmap failed, ret = %d\n", __func__, __LINE__, ret); ++ } ++ if (LARGE == memInfo.type) ++ { ++ ret = qae_munmap(slab, getpagesize()); ++ if (ret) ++ { ++ CMD_ERROR( ++ "%s:%d munmap failed, ret = %d\n", __func__, __LINE__, ret); ++ } ++ } ++ ++#ifndef __FreeBSD__ ++ if (HUGE_PAGE == memInfo.type) ++ { ++ hugepage_free_slab(&memInfo); ++ } ++ else ++#endif ++ { ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, &memInfo); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ } ++} ++ ++static inline dev_mem_info_t *find_slab(const int fd, ++ const size_t size, ++ const int node, ++ void **addr, ++ const size_t align) ++{ ++ dev_mem_info_t *slab = userMemLookupBySize(size, node, addr, align); ++ ++ if (NULL == slab) ++ { ++ slab = pop_slab(node); ++ if (NULL != slab) ++ { ++ *addr = init_slab_and_alloc((block_ctrl_t *)slab, size, align); ++ if (NULL == *addr) ++ { ++ CMD_ERROR("%s:%d Memory allocation failed Virtual address: %p " ++ " Size: %x \n", ++ __func__, ++ __LINE__, ++ slab, ++ size); ++ free_slab(fd, slab); ++ return NULL; ++ } ++ } ++ } ++ return slab; ++} ++ ++/************************************** ++ * Memory functions ++ *************************************/ ++void *qaeMemAlloc(size_t memsize) ++{ ++ void *memPtr = NULL; ++ memPtr = calloc(memsize, sizeof(uint8_t)); ++ return memPtr; ++} ++ ++void qaeMemFree(void **ptr) ++{ ++ if ((!ptr) || !(*ptr)) ++ { ++ CMD_ERROR("%s:%d Trying to Free NULL Pointer\n", __func__, __LINE__); ++ return; ++ } ++ free(*ptr); ++ *ptr = NULL; ++} ++ ++static inline int check_pid(void) ++{ ++ static pid_t pid = 0; ++ ++ if (pid != getpid()) ++ { ++ pid = getpid(); ++ return 1; ++ } ++ return 0; ++} ++ ++static inline int qaeOpenFd(void) ++{ ++ /* Check if it is a new process or child. */ ++ const int is_new_pid = check_pid(); ++ ++ if (fd < 0 || is_new_pid) ++ { ++ /* Reset all control structures. */ ++ free_page_table_fptr(&g_page_table); ++ memset(&g_page_table, 0, sizeof(g_page_table)); ++ memset(&g_slab_list, 0, sizeof(g_slab_list)); ++ g_cache_size = 0; ++ ++ pUserCacheHead = NULL; ++ pUserCacheTail = NULL; ++ pUserMemListHead = NULL; ++ pUserMemListTail = NULL; ++ pUserLargeMemListHead = NULL; ++ pUserLargeMemListTail = NULL; ++ ++ CMD_DEBUG("%s:%d Memory file handle is not initialized. " ++ "Initializing it now \n", ++ __func__, ++ __LINE__); ++ ++ if (fd > 0) ++ close(fd); ++ fd = qae_open(QAE_MEM, O_RDWR); ++ if (fd < 0) ++ { ++ CMD_ERROR("%s:%d Unable to initialize memory file handle %s \n", ++ __func__, ++ __LINE__, ++ QAE_MEM); ++ return -ENOENT; ++ } ++ ++ if (init_hugepages(fd)) ++ return -EIO; ++ } ++ return 0; ++} ++ ++int32_t qaeMemInit() ++{ ++ int32_t fd_status = 0; ++ int32_t status = 0; ++ ++ status = mem_mutex_lock(&mutex); ++ if (status) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(status)); ++ return -EIO; ++ } ++ ++ fd_status = qaeOpenFd(); ++ ++ status = mem_mutex_unlock(&mutex); ++ if (status) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(status)); ++ return -EIO; ++ } ++ return fd_status; ++} ++ ++#ifdef __FreeBSD__ ++int qaeMemInitAndReturnFd(int *mem_fd) ++{ ++ int status = -1; ++ if (NULL != mem_fd) ++ { ++ status = qaeMemInit(); ++ } ++ if (status == 0) ++ { ++ *mem_fd = fd; ++ } ++ return status; ++} ++#endif /* __FreeBSD__ */ ++ ++static void destroyList(const int fd, dev_mem_info_t *pList) ++{ ++ dev_mem_info_t *pCurr = pList; ++ ++ while (pCurr) ++ { ++ dev_mem_info_t *next = pCurr->pNext_user; ++ free_slab(fd, pCurr); ++ pCurr = next; ++ } ++} ++ ++static inline void reset_cache(const int fd) ++{ ++ dev_mem_info_t *slab = NULL; ++ do ++ { ++ slab = pop_slab(NUMA_ANY_NODE); ++ if (NULL != slab) ++ free_slab(fd, slab); ++ } while (slab != NULL); ++} ++ ++void qaeMemDestroy(void) ++{ ++ int ret = 0; ++ ++ /* Free all of the chains */ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR( ++ "%s:%d Error(%d) on thread mutex lock \n", __func__, __LINE__, ret); ++ return; ++ } ++ ++ /* release all control buffers */ ++ free_page_table_fptr(&g_page_table); ++ reset_cache(fd); ++ destroyList(fd, pUserMemListHead); ++ destroyList(fd, pUserLargeMemListHead); ++ ++ pUserCacheHead = NULL; ++ pUserCacheTail = NULL; ++ pUserMemListHead = NULL; ++ pUserMemListTail = NULL; ++ pUserLargeMemListHead = NULL; ++ pUserLargeMemListTail = NULL; ++ ++ /* Send ioctl to kernel space to remove block for this pid */ ++ if (fd > 0) ++ { ++ ret = mem_ioctl(fd, DEV_MEM_IOC_RELEASE, NULL); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem release failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ close(fd); ++ fd = -1; ++ } ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error(%d) on thread mutex unlock\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++} ++ ++#ifndef __FreeBSD__ ++static inline void *mem_protect(void *const addr, const size_t len) ++{ ++ int ret = 0; ++ ++ ret = qae_madvise(addr, len, MADV_DONTFORK); ++ if (0 != ret) ++ { ++ munmap(addr, len); ++ return NULL; ++ } ++ return addr; ++} ++#endif ++ ++static inline void *mmap_phy_addr(const int fd, ++ const uint64_t phy_addr, ++ const size_t len) ++{ ++ void *addr = NULL; ++ ++#ifdef __FreeBSD__ ++ addr = ++ qae_mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, phy_addr); ++ if (0 != mlock(addr, len)) ++ { ++ munmap(addr, len); ++ return NULL; ++ } ++#endif ++#ifndef __FreeBSD__ ++ addr = qae_mmap(NULL, ++ len, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_LOCKED, ++ fd, ++ phy_addr); ++#endif ++ ++ if (MAP_FAILED == addr) ++ return NULL; ++ ++#ifndef __FreeBSD__ ++ addr = mem_protect(addr, len); ++#endif ++ ++ return addr; ++} ++ ++static inline dev_mem_info_t *ioctl_alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t params = {0}; ++ int ret = 0; ++ dev_mem_info_t *slab = NULL; ++ ++ params.size = size; ++ params.nodeId = node; ++ params.type = type; ++ ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMALLOC, ¶ms); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem allocation failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ return NULL; ++ } ++ ++ if (node != params.nodeId) ++ { ++ g_strict_node = 0; ++ } ++ ++ if (SMALL == type) ++ slab = mmap_phy_addr(fd, params.phy_addr, params.size); ++ else ++ slab = mmap_phy_addr(fd, params.phy_addr, getpagesize()); ++ ++ if (NULL == slab) ++ { ++ CMD_ERROR("%s:%d mmap on memory allocated through ioctl failed\n", ++ __func__, ++ __LINE__); ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, ¶ms); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ return NULL; ++ } ++ ++ if (SMALL == type) ++ slab->virt_addr = slab; ++ else ++ { ++ slab->virt_addr = mmap_phy_addr(fd, params.phy_addr, params.size); ++ ++ if (NULL == slab->virt_addr) ++ { ++ CMD_ERROR("%s:%d mmap failed for large memory allocation\n", ++ __func__, ++ __LINE__); ++ munmap(slab, getpagesize()); ++ ret = mem_ioctl(fd, DEV_MEM_IOC_MEMFREE, ¶ms); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d ioctl call for mem free failed, ret = %d\n", ++ __func__, ++ __LINE__, ++ ret); ++ } ++ return NULL; ++ } ++ } ++ ++ return slab; ++} ++ ++static inline dev_mem_info_t *alloc_slab(const int fd, ++ const size_t size, ++ const int node, ++ enum slabType type) ++{ ++ dev_mem_info_t *slab = NULL; ++ ++ if (HUGE_PAGE == type) ++ { ++#ifndef __FreeBSD__ ++ slab = hugepage_alloc_slab(fd, size, node, type); ++#endif ++ } ++ else ++ { ++ slab = ioctl_alloc_slab(fd, size, node, type); ++ } ++ ++ /* Store a slab into the hash table for a fast lookup. */ ++ if (slab) ++ add_slab_to_hash(slab); ++ ++ return slab; ++} ++ ++static inline void *alloc_addr(size_t size, ++ const int node, ++ const size_t phys_alignment_byte) ++{ ++ dev_mem_info_t *p_ctrl_blk = NULL; ++ void *pVirtAddress = NULL; ++ size_t allocate_pages = 0; ++ enum slabType mem_type = SMALL; ++ ++ const size_t phys_align_unit = phys_alignment_byte / UNIT_SIZE; ++ const size_t reserved = div_round_up(sizeof(block_ctrl_t), UNIT_SIZE); ++ /* calculate units needed */ ++ const size_t requested_pages = div_round_up(size, UNIT_SIZE) + reserved; ++ ++ if (0 != qaeOpenFd()) ++ return NULL; ++ ++ if (requested_pages > QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / UNIT_SIZE || ++ phys_alignment_byte >= QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE) ++ { ++ mem_type = LARGE; ++ /* Huge page and Large memory are mutually exclusive ++ * Since Large slabs are NOT 2 MB aligned, but huge ++ * pages are always 2 MB aligned. ++ */ ++ if (hugepage_enabled()) ++ return NULL; ++ ++ size = MAX(size, phys_alignment_byte); ++ allocate_pages = div_round_up(size, UNIT_SIZE); ++ } ++ else ++ { ++ allocate_pages = QAE_NUM_PAGES_PER_ALLOC * QAE_PAGE_SIZE / UNIT_SIZE; ++ if (hugepage_enabled()) ++ mem_type = HUGE_PAGE; ++ ++ p_ctrl_blk = find_slab(fd, size, node, &pVirtAddress, phys_align_unit); ++ ++ if (p_ctrl_blk) ++ { ++ p_ctrl_blk->allocations += 1; ++ return pVirtAddress; ++ } ++ } ++ ++ /* Try to allocate memory as much as possible */ ++ p_ctrl_blk = alloc_slab(fd, allocate_pages * UNIT_SIZE, node, mem_type); ++ if (NULL == p_ctrl_blk) ++ return NULL; ++ ++ store_mmap_range(&g_page_table, ++ p_ctrl_blk->virt_addr, ++ p_ctrl_blk->phy_addr, ++ p_ctrl_blk->size, ++ hugepage_enabled()); ++ ++ if (LARGE == mem_type) ++ { ++ p_ctrl_blk->allocations = 1; ++ ++ ADD_ELEMENT_TO_HEAD_LIST( ++ p_ctrl_blk, pUserLargeMemListHead, pUserLargeMemListTail, _user); ++ ++ pVirtAddress = p_ctrl_blk->virt_addr; ++ } ++ else ++ { ++ p_ctrl_blk->allocations = 1; ++ ++ if ((uintptr_t)p_ctrl_blk->virt_addr % QAE_PAGE_SIZE) ++ { ++ CMD_ERROR("%s:%d Bad virtual address alignment %lux %x %lux\n", ++ __func__, ++ __LINE__, ++ (uintptr_t)p_ctrl_blk->virt_addr, ++ QAE_NUM_PAGES_PER_ALLOC, ++ QAE_PAGE_SIZE); ++ free_slab(fd, p_ctrl_blk); ++ ++ return NULL; ++ } ++ pVirtAddress = init_slab_and_alloc( ++ (block_ctrl_t *)p_ctrl_blk, size, phys_align_unit); ++ if (NULL == pVirtAddress) ++ { ++ CMD_ERROR("%s:%d Memory allocation failed Virtual address: %p " ++ " Size: %x \n", ++ __func__, ++ __LINE__, ++ p_ctrl_blk, ++ size); ++ free_slab(fd, p_ctrl_blk); ++ ++ return NULL; ++ } ++ } ++ return pVirtAddress; ++} ++ ++void *qaeMemAllocNUMA(size_t size, int node, size_t phys_alignment_byte) ++{ ++ void *pVirtAddress = NULL; ++ int ret = 0; ++ /* Maximum supported alignment is 4M. */ ++ const size_t MAX_PHYS_ALIGN = 0x400000; ++ ++ if (!size) ++ { ++ CMD_ERROR("%s:%d Size cannot be zero \n", __func__, __LINE__); ++ return NULL; ++ } ++ ++ if (!phys_alignment_byte || phys_alignment_byte > MAX_PHYS_ALIGN || ++ (phys_alignment_byte & (phys_alignment_byte - 1))) ++ { ++ CMD_ERROR("%s:%d Invalid alignment parameter %d. It must be non zero, " ++ "not more than %d and multiple of 2 \n", ++ __func__, ++ __LINE__, ++ phys_alignment_byte, ++ MAX_PHYS_ALIGN); ++ return NULL; ++ } ++ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ return NULL; ++ } ++ ++ pVirtAddress = alloc_addr(size, node, phys_alignment_byte); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ return NULL; ++ } ++ return pVirtAddress; ++} ++ ++static inline void free_addr(void **p_va) ++{ ++ dev_mem_info_t *p_ctrl_blk = NULL; ++ ++ if (0 != qaeOpenFd()) ++ return; ++ ++ if ((p_ctrl_blk = find_slab_in_hash(*p_va)) == NULL) ++ { ++ CMD_ERROR("%s:%d Unable to free as lookup failed on address (%p) " ++ "provided \n", ++ __func__, ++ __LINE__, ++ *p_va); ++ return; ++ } ++ if (SMALL == p_ctrl_blk->type || HUGE_PAGE == p_ctrl_blk->type) ++ { ++ mem_free((block_ctrl_t *)p_ctrl_blk, *p_va); ++ ++ p_ctrl_blk->allocations -= 1; ++ ++ if (p_ctrl_blk->allocations) ++ { ++ *p_va = NULL; ++ return; ++ } ++ ++ REMOVE_ELEMENT_FROM_LIST( ++ p_ctrl_blk, pUserMemListHead, pUserMemListTail, _user); ++ if (0 != push_slab(p_ctrl_blk)) ++ free_slab(fd, p_ctrl_blk); ++ } ++ else ++ { ++ REMOVE_ELEMENT_FROM_LIST( ++ p_ctrl_blk, pUserLargeMemListHead, pUserLargeMemListTail, _user); ++ free_slab(fd, p_ctrl_blk); ++ } ++ *p_va = NULL; ++} ++ ++void qaeMemFreeNUMA(void **ptr) ++{ ++ int ret = 0; ++ ++ if (NULL == ptr) ++ { ++ CMD_ERROR( ++ "%s:%d Input parameter cannot be NULL \n", __func__, __LINE__); ++ return; ++ } ++ if (NULL == *ptr) ++ { ++ CMD_ERROR( ++ "%s:%d Address to be freed cannot be NULL \n", __func__, __LINE__); ++ return; ++ } ++ ret = mem_mutex_lock(&mutex); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex lock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ *ptr = NULL; ++ return; ++ } ++ ++ free_addr(ptr); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (ret) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ } ++ return; ++} ++ ++/*translate a virtual address to a physical address */ ++uint64_t qaeVirtToPhysNUMA(void *pVirtAddress) ++{ ++ return load_addr_fptr(&g_page_table, pVirtAddress); ++} ++ ++static int32_t memoryRemap(dev_mem_info_t *head) ++{ ++ // NOT SUPPORTED ++ if (NULL != head) ++ { ++ CMD_ERROR("%s:%d not supported \n", __func__, __LINE__); ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++void qaeAtFork() ++{ ++ int ret = 0; ++ int32_t status0 = 0; ++ int32_t status1 = 0; ++ int32_t status2 = 0; ++ ++ ret = mem_mutex_lock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR( ++ "%s:%d Error(%d) on thread mutex lock \n", __func__, __LINE__, ret); ++ return; ++ } ++ ++ status0 = memoryRemap(pUserCacheHead); ++ status1 = memoryRemap(pUserMemListHead); ++ status2 = memoryRemap(pUserLargeMemListHead); ++ ++ ret = mem_mutex_unlock(&mutex); ++ if (unlikely(ret)) ++ { ++ CMD_ERROR("%s:%d Error on thread mutex unlock %s\n", ++ __func__, ++ __LINE__, ++ strerror(ret)); ++ goto fork_exit; ++ } ++ ++fork_exit: ++ if (unlikely(status0)) ++ { ++ CMD_ERROR( ++ "%s:%d Failed to remap memory allocations \n", __func__, __LINE__); ++ } ++ if (unlikely(status1)) ++ { ++ CMD_ERROR( ++ "%s:%d Failed to remap memory allocations \n", __func__, __LINE__); ++ } ++ if (unlikely(status2)) ++ { ++ CMD_ERROR("%s:%d Failed to remap large memory allocations \n", ++ __func__, ++ __LINE__); ++ } ++ return; ++} +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/linux/user_space/qae_page_table.h +@@ -0,0 +1,431 @@ ++/******************************************************************************* ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ * @file qae_page_table.h ++ * ++ * This file provides user-space page tables (similar to Intel x86/x64 ++ * page tables) for fast virtual to physical address translation. Essentially, ++ * this is an implementation of the trie data structure optimized for the x86 HW ++ * constraints. ++ * Memory required: ++ * - 8 Mb to cover 4 Gb address space. ++ * I.e. if only 1 Gb is used it will require additional 2 Mb. ++ * ++ ******************************************************************************/ ++ ++#ifndef QAE_PAGE_TABLE_H_1 ++#define QAE_PAGE_TABLE_H_1 ++ ++#define __STDC_WANT_LIB_EXT1__ 1 ++#include ++#include ++#ifdef __linux__ ++#include ++#endif ++ ++#ifndef __FreeBSD__ /* FreeBSD, already defined in machine param.h */ ++#define PAGE_SIZE (0x1000) ++#define PAGE_SHIFT (12) ++#endif ++ ++#define QAE_PAGE_MASK (~(PAGE_SIZE - 1)) ++#define LEVEL_SIZE (PAGE_SIZE / sizeof(uint64_t)) ++ ++#define HUGEPAGE_SIZE (0x200000) ++#define HUGEPAGE_SHIFT (21) ++#define HUGEPAGE_MASK (~(HUGEPAGE_SIZE - 1)) ++ ++typedef struct ++{ ++ uint64_t offset : 12; ++ uint64_t idxl0 : 9; ++ uint64_t idxl1 : 9; ++ uint64_t idxl2 : 9; ++ uint64_t idxl3 : 9; ++ uint64_t idxl4 : 9; ++} page_entry_t; ++ ++typedef struct ++{ ++ uint64_t offset : 21; ++ uint64_t idxl1 : 9; ++ uint64_t idxl2 : 9; ++ uint64_t idxl3 : 9; ++ uint64_t idxl4 : 9; ++} hugepage_entry_t; ++ ++typedef union { ++ uint64_t addr; ++ page_entry_t pg_entry; ++ hugepage_entry_t hpg_entry; ++} page_index_t; ++ ++typedef struct page_table_t ++{ ++ union { ++ uint64_t pa; ++ struct page_table_t *pt; ++ } next[LEVEL_SIZE]; ++} page_table_t; ++ ++typedef void (*free_page_table_fptr_t)(page_table_t *const table); ++typedef void (*store_addr_fptr_t)(page_table_t *, uintptr_t, uint64_t); ++typedef uint64_t (*load_addr_fptr_t)(page_table_t *, void *); ++typedef uint64_t (*load_key_fptr_t)(page_table_t *, void *); ++ ++#ifndef __FreeBSD__ ++void set_free_page_table_fptr(free_page_table_fptr_t fp); ++void set_loadaddr_fptr(load_addr_fptr_t fp); ++void set_loadkey_fptr(load_key_fptr_t fp); ++#endif /* __FreeBSD__ */ ++ ++static inline void *qae_memzero(void *const ptr, const size_t count) ++{ ++ uint32_t lim = 0; ++ volatile unsigned char *volatile dstPtr = ptr; ++ ++ while (lim < count) ++ { ++ dstPtr[lim++] = '\0'; ++ } ++ return (void *)dstPtr; ++} ++ ++/* ++ * Fills a memory zone with 0, ++ * returns pointer to the memory zone. ++ */ ++static inline void *qae_memzero_explicit(void *const ptr, const size_t count) ++{ ++ if (!ptr) ++ { ++ return NULL; ++ } ++#if (defined(__linux__)) ++#ifdef __STDC_LIB_EXT1__ ++ errno_t result = ++ memset_s(ptr, sizeof(ptr), 0, count); /* Supported on C11 standard */ ++ if (result != 0) ++ { ++ return NULL; ++ } ++ return ptr; ++#endif /* __STDC_LIB_EXT1__ */ ++#elif (defined(__FreeBSD__)) ++ explicit_bzero(ptr, count); ++ return ptr; ++#endif /* __linux__ */ ++ return qae_memzero(ptr, count); /* Platform-independent secure memset */ ++} ++ ++static inline void *next_level(page_table_t *volatile *ptr) ++{ ++ page_table_t *old_ptr = *ptr; ++ page_table_t *new_ptr; ++ ++ if (NULL != old_ptr) ++ return old_ptr; ++ ++ new_ptr = mmap(NULL, ++ sizeof(page_table_t), ++ PROT_READ | PROT_WRITE, ++ MAP_PRIVATE | MAP_ANONYMOUS, ++ -1, ++ 0); ++ if ((void *)-1 == new_ptr) ++ return NULL; ++ ++ if (!__sync_bool_compare_and_swap(ptr, NULL, new_ptr)) ++ munmap(new_ptr, sizeof(page_table_t)); ++ ++ return *ptr; ++} ++ ++static inline void free_page_level(page_table_t *const level, const size_t iter) ++{ ++ size_t i = 0; ++ ++ if (0 == iter) ++ return; ++ ++ for (i = 0; i < LEVEL_SIZE; ++i) ++ { ++ page_table_t *pt = level->next[i].pt; ++ if (NULL != pt) ++ { ++ free_page_level(pt, iter - 1); ++ munmap(pt, sizeof(page_table_t)); ++ } ++ } ++} ++ ++static inline void free_page_table(page_table_t *const table) ++{ ++ /* There are 1+4 levels in 64-bit page table for 4KB pages. */ ++ free_page_level(table, 4); ++ /* Reset global root table. */ ++ memset(table, 0, sizeof(page_table_t)); ++} ++ ++#ifndef __FreeBSD__ ++static inline void free_page_table_hpg(page_table_t *const table) ++{ ++ /* There are 1+3 levels in 64-bit page table for 2MB hugepages. */ ++ free_page_level(table, 3); ++ /* Reset global root table. */ ++ memset(table, 0, sizeof(page_table_t)); ++} ++#endif /*__FreeBSD__ */ ++ ++static inline void store_addr(page_table_t *level, ++ uintptr_t virt, ++ uint64_t phys) ++{ ++ page_index_t id; ++ ++ id.addr = virt; ++ ++ level = next_level(&level->next[id.pg_entry.idxl4].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl3].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl2].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.pg_entry.idxl1].pt); ++ if (NULL == level) ++ return; ++ ++ level->next[id.pg_entry.idxl0].pa = phys; ++} ++ ++static inline void store_addr_hpg(page_table_t *level, ++ uintptr_t virt, ++ uint64_t phys) ++{ ++ page_index_t id; ++ ++ id.addr = virt; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl4].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl3].pt); ++ if (NULL == level) ++ return; ++ ++ level = next_level(&level->next[id.hpg_entry.idxl2].pt); ++ if (NULL == level) ++ return; ++ ++ level->next[id.hpg_entry.idxl1].pa = phys; ++} ++ ++static inline uint64_t get_key(const uint64_t phys) ++{ ++ /* For 4KB page: use bits 20-31 of a physical address as a hash key. ++ * It provides a good distribution for 1Mb/2Mb slabs and a moderate ++ * distribution for 128Kb/256Kb/512Kbslabs. ++ */ ++ return (phys >> 20) & ~QAE_PAGE_MASK; ++} ++ ++static inline void store_mmap_range(page_table_t *p_level, ++ void *p_virt, ++ uint64_t p_phys, ++ size_t p_size, ++ int hp_en) ++{ ++ size_t offset; ++ size_t page_size = PAGE_SIZE; ++ uint64_t page_mask = QAE_PAGE_MASK; ++ store_addr_fptr_t store_addr_ptr = store_addr; ++ const uintptr_t virt = (uintptr_t)p_virt; ++ ++ if (hp_en) ++ { ++ page_size = HUGEPAGE_SIZE; ++ page_mask = HUGEPAGE_MASK; ++ store_addr_ptr = store_addr_hpg; ++ } ++ /* Store the key into the physical address itself, ++ * for 4KB pages: 12 lower bits are always 0 (physical page addresses ++ * are 4KB-aligned). ++ * for 2MB pages: 21 lower bits are always 0 (physical page addresses ++ * are 2MB-aligned) ++ */ ++ p_phys = (p_phys & page_mask) | get_key(p_phys); ++ for (offset = 0; offset < p_size; offset += page_size) ++ { ++ store_addr_ptr(p_level, virt + offset, p_phys + offset); ++ } ++} ++ ++static inline uint64_t load_addr(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.pg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl1].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.pg_entry.idxl0].pa; ++ return (phy_addr & QAE_PAGE_MASK) | id.pg_entry.offset; ++} ++ ++static inline uint64_t load_addr_hpg(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.hpg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.hpg_entry.idxl1].pa; ++ return (phy_addr & HUGEPAGE_MASK) | id.hpg_entry.offset; ++} ++ ++static inline uint64_t load_key(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.pg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.pg_entry.idxl1].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.pg_entry.idxl0].pa; ++ return phy_addr & ~QAE_PAGE_MASK; ++} ++ ++#ifndef __FreeBSD__ ++static inline uint64_t load_key_hpg(page_table_t *level, void *virt) ++{ ++ page_index_t id; ++ uint64_t phy_addr; ++ ++ id.addr = (uintptr_t)virt; ++ ++ level = level->next[id.hpg_entry.idxl4].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl3].pt; ++ if (NULL == level) ++ return 0; ++ ++ level = level->next[id.hpg_entry.idxl2].pt; ++ if (NULL == level) ++ return 0; ++ ++ phy_addr = level->next[id.hpg_entry.idxl1].pa; ++ /* the hash key is of 4KB long for both normal page and huge page */ ++ return phy_addr & ~QAE_PAGE_MASK; ++} ++#endif /* __FreeBSD__ */ ++ ++#endif +--- /dev/null ++++ b/quickassist/utilities/libusdm_drv/qae_mem.h +@@ -0,0 +1,244 @@ ++/*************************************************************************** ++ * ++ * This file is provided under a dual BSD/GPLv2 license. When using or ++ * redistributing this file, you may do so under either license. ++ * ++ * GPL LICENSE SUMMARY ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of version 2 of the GNU General Public License as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. ++ * The full GNU General Public License is included in this distribution ++ * in the file called LICENSE.GPL. ++ * ++ * Contact Information: ++ * Intel Corporation ++ * ++ * BSD LICENSE ++ * ++ * Copyright(c) 2007-2019 Intel Corporation. All rights reserved. ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Intel Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * ++ * version: QAT1.7.L.4.7.0-00006 ++ * ++ ***************************************************************************/ ++/** ++ *************************************************************************** ++ * @file qae_mem.h ++ * ++ * This file provides linux/FreeBSD memory allocation for quick assist API ++ * ++ ****************************************************************************/ ++#ifndef QAE_MEM_H_ ++#define QAE_MEM_H_ ++ ++#ifdef __KERNEL__ ++#ifdef __FreeBSD__ ++#include ++#else ++#include ++#endif ++#else ++#include ++#endif ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemAlloc ++ * ++ * @brief ++ * When used in user space, allocates memsize bytes of virtual memory. ++ * When used in kernel space, allocates memsize bytes of contigous and ++ * pinned memory. ++ * ++ * @param[in] memsize - the amount of memory in bytes to be allocated ++ * ++ * @retval pointer to the allocated memory or NULL if the allocation failed ++ * ++ * @pre ++ * none ++ * @post ++ * memory is allocated and the pointer to the allocated memory location ++ * is returned ++ * ++ ****************************************************************************/ ++void *qaeMemAlloc(size_t memsize); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemFree ++ * ++ * @brief ++ * Frees memory allocated by the qaeMemAlloc function. ++ * Applicable for both user and kernel spaces. ++ * ++ * @param[in] ptr - Address of the pointer to the memory to be freed ++ * ++ * @retval none ++ * ++ * @pre ++ * *ptr points to memory previously allocated by qaeMemAlloc ++ * @post ++ * memory is freed and pointer value is set to NULL ++ * ++ ****************************************************************************/ ++void qaeMemFree(void **ptr); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemAllocNUMA ++ * ++ * @brief ++ * Allocates and returns virtual memory mapped to pinned, contiguous ++ * physical memory aligned to phys_alignment_byte. This API enables ++ * user to choose a CPU node nearest to QAT device. This API is applicable ++ * for both user and kernel spaces. Based on the address space used, ++ * memory mapped from corresponding virtual address space will be returned. ++ * ++ * @param[in] size - A non-zero value representing the amount of memory in ++ * bytes to be allocated.It cannot exceed 4MB ++ * @param[in] node - NUMA node ++ * @param[in] phys_alignment_byte - A non-zero value representing memory ++ * boundary alignment in bytes. It must ++ * be in powers of 2 not exceeding 4KB. ++ * ++ * @retval pointer to the allocated memory or NULL if the allocation failed ++ * ++ * @pre ++ * none ++ * @post ++ * memory is allocated and pointer to the allocated memory is returned ++ * ++ ****************************************************************************/ ++void *qaeMemAllocNUMA(size_t size, int node, size_t phys_alignment_byte); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemFreeNUMA ++ * ++ * @brief ++ * Frees memory allocated by the qaeMemAllocNUMA function. ++ * Applicable for both user and kernel spaces. ++ * ++ * @param[in] ptr - Address of pointer to the memory to be freed ++ * ++ * @retval none ++ * ++ * @pre ++ * *ptr points to memory previously allocated by qaeMemAllocNUMA ++ * @post ++ * memory is freed and the pointer value is set to NULL ++ * ++ ****************************************************************************/ ++void qaeMemFreeNUMA(void **ptr); ++ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeVirtToPhysNUMA ++ * ++ * @brief ++ * Converts a virtual address provided by qaeMemAllocNUMA to a ++ * physical one. Applicable for both user and kernel spaces. ++ * ++ * @param[in] pVirtAddr - pointer to the virtual address ++ * ++ * @retval pointer to the physical address or 0(NULL) on error ++ * ++ * @pre ++ * pVirtAddr points to memory previously allocated by qaeMemAllocNUMA ++ * @post ++ * Appropriate physical address is provided ++ * ++ ****************************************************************************/ ++uint64_t qaeVirtToPhysNUMA(void *pVirtAddr); ++ ++#ifdef __FreeBSD__ ++/** ++ ***************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeMemInitAndReturnFd ++ * ++ * @description ++ * Returns the FD obtained by qaeMemInit ++ * ++ * @param[in] ++ * ptr - Address of fd which is updated by qaeMemInit ++ * ++ * @retval ++ * status from qaeMemInit. 0 if the open of the device was successful and ++ * non-zero otherwise ++ * ++ * @pre ++ * File "/dev/qae_mem" is opened successfully ++ * @post ++ * none ++ * ++ ****************************************************************************/ ++int qaeMemInitAndReturnFd(int *mem_fd); ++#endif ++ ++#ifndef __KERNEL__ ++/*! Define a constant for user space to select any available NUMA node */ ++#define NUMA_ANY_NODE (-1) ++ ++/** ++ *************************************************************************** ++ * @ingroup CommonMemoryDriver ++ * qaeAtFork ++ * ++ * @brief ++ * Must be called when child process is forked to adjust the kernel ++ * memory map page. ++ * ++ * @param[in] - none ++ * ++ * @retval none ++ * ++ ****************************************************************************/ ++void qaeAtFork(void); ++#endif ++ ++#endif /* #ifndef QAE_MEM_H_ */ +--- a/quickassist/include/cpa.h ++++ b/quickassist/include/cpa.h +@@ -694,13 +694,21 @@ typedef enum _CpaInstanceEvent + * implementation may send this event if the hardware device is about to + * be reset. + */ +- CPA_INSTANCE_EVENT_RESTARTED ++ CPA_INSTANCE_EVENT_RESTARTED, + /**< Event type that triggers the registered instance notification callback + * function when and instance has restarted. The reason why an instance has + * restarted is implementation specific. For example a hardware + * implementation may send this event after the hardware device has + * been reset. + */ ++ ++ CPA_INSTANCE_EVENT_FATAL_ERROR ++ /**< Event type that triggers the registered instance notification callback ++ * function when an error has been detected that requires the device ++ * to be reset. ++ * This event will be sent by all instances using the device, both on the ++ * host and guests. ++ */ + } CpaInstanceEvent; + + #ifdef __cplusplus diff --git a/package/qat/firmware/quickassist-c3xxx/Config.in b/package/qat/firmware/quickassist-c3xxx/Config.in new file mode 100644 index 000000000..97c65cde5 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Config.in @@ -0,0 +1,104 @@ +menu "Configuration" + depends on PACKAGE_quickassist-c3xxx + + config QAT_C3XXX_KERNEL_OPTIONS + bool + default n + prompt "Required kernel options for Quickassist" + select KERNEL_ASN1 + select KERNEL_CRYPTO_AKCIPHER + select KERNEL_CRYPTO_AKCIPHER2 + select KERNEL_CRYPTO_DH + select KERNEL_CRYPTO_HW + select KERNEL_CRYPTO_KPP + select KERNEL_CRYPTO_KPP2 + select KERNEL_CRYPTO_RSA + select KERNEL_UIO + select KERNEL_PCI_IOV + select KERNEL_HUGETLBFS + select KERNEL_HUGETLB_PAGE + help + These kernel options are required for successful compilation and runtime functionality. + + config QAT_DEBUG + bool + default n + prompt "Build with debugging support enabled" + + config QAT_DISABLE_STATS + bool + default n + prompt "Disable statistics collection" + help + Disable for performance optimization + + config QAT_LOG_SYSLOG + bool + default y + prompt "Debug to syslog instead of stdout" + + config QAT_PARAM_CHECK + bool + default y + prompt "Enable parameter checking in the top-level APIs" + help + Disable for performance optimization + + config QAT_NONBLOCKING_PARTIALS + bool + default y + prompt "Partial operation results are non-blocking" + help + Disable for performance optimization + + config QAT_DC_ONLY + bool + default n + prompt "Build acceleration only for compression" + help + Optimize for size if using only compression + + config QAT_DC_SYM_ONLY + bool + default n + prompt "Build acceleration only for compression and symmetric ciphers" + help + Optimize for size if using only compression and symmetric ciphers + + config QAT_DC_COUNTER_ERROR + bool + default n + prompt "Update counters when encountering an error" + help + Enables updates of consumed/produced results in case + of error during compression or decompression operations + + config QAT_DISABLE_INLINE + bool + default n + prompt "Disable functioning inlining for functions that cannot be inlined by the compiler" + help + Use where kernel does not support CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING to allow building + + config QAT_HB_FAIL + bool + default n + prompt "Enable heartbeat failure simulation" + + config QAT_COEXIST + bool + default n + prompt "Enable legacy and upstream driver coexistence" + + config QAT_LKCF + bool + default y + prompt "Enable QAT registration with Linux Kernel Crypto Framework" + + config QAT_DISABLE_STRICT + bool + default n + prompt "Disable strict mode for data compression" + +endmenu + diff --git a/package/qat/firmware/quickassist-c3xxx/Config.kernel b/package/qat/firmware/quickassist-c3xxx/Config.kernel new file mode 100644 index 000000000..0874bbf9f --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Config.kernel @@ -0,0 +1,97 @@ +config KERNEL_ASN1 + bool + default n + +config KERNEL_CRYPTO_AKCIPHER + bool + default n + +config KERNEL_CRYPTO_AKCIPHER2 + bool + default n + +config KERNEL_CRYPTO_DH + bool + default n + +config KERNEL_CRYPTO_KPP + bool + default n + +config KERNEL_CRYPTO_KPP2 + bool + default n + +config KERNEL_CRYPTO_RSA + bool + default n + +config KERNEL_HUGETLBFS + bool + default n + +config KERNEL_HUGETLB_PAGE + bool + default n + +config KERNEL_CRYPTO_HW + bool + default n + +config KERNEL_UIO + bool + default n + +config KERNEL_PCI_IOV + bool + default n + +# CONFIG_UIO is not set in generic and x86 kernels +# Avoid prompting the user for input of dependent symbols + +config KERNEL_UIO_CIF + bool + default n + +config KERNEL_UIO_PDRV_GENIRQ + bool + default n + +config KERNEL_UIO_DMEM_GENIRQ + bool + default n + +config KERNEL_UIO_AEC + bool + default n + +config KERNEL_UIO_SERCOS3 + bool + default n + +config KERNEL_UIO_PCI_GENERIC + bool + default n + +config KERNEL_UIO_NETX + bool + default n + +config KERNEL_UIO_PRUSS + bool + default n + +config KERNEL_UIO_MF624 + bool + default n + +config KERNEL_UIO_HV_GENERIC + bool + default n + +# CONFIG_STAGING is set in generic +# CONFIG_KPC2000 depends on PCI and UIO + +config KERNEL_KPC2000 + bool + default n diff --git a/package/qat/firmware/quickassist-c3xxx/Makefile b/package/qat/firmware/quickassist-c3xxx/Makefile new file mode 100644 index 000000000..55160d68e --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/Makefile @@ -0,0 +1,236 @@ +# +# Copyright (C) Ian Cooper +# +# This is free software, licensed under the GNU General Public License v3. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=quickassist-c3xxx + +PKG_VERSION:=1.7 +PKG_MINOR_VERSION:=L.4.13.0-00009 +PKG_RELEASE:=1 + +PKG_SOURCE:=QAT$(PKG_VERSION).$(PKG_MINOR_VERSION).tar.gz +PKG_SOURCE_URL:=https://downloadmirror.intel.com/30178/eng/ +PKG_HASH:=skip + +PKG_LICENSE:=GPL v3 + +PKG_BUILD_DEPENDS:=eudev openssl +QAT_DEFAULT_DEPENDS:= @TARGET_x86_64 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_PARALLEL:=0 + +QAT_BUILD = $(PKG_BUILD_DIR)/build +QAT_BLDSYS = $(PKG_BUILD_DIR)/quickassist/build_system +QAT_OOT = $(PKG_BUILD_DIR)/quickassist/qat +QAT_ADF = $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl +QAT_ENV = $(PKG_BUILD_DIR)/quickassist/build_system/build_files/env_files + +define Package/quickassist-c3xxx + SECTION:=firmware + CATEGORY:=Firmware + TITLE:=Intel Quick Assist Technology for c3xxx SoC + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + $(PKG_DEFAULT_DEPENDS) \ + +libopenssl \ + +libstdcpp \ + +eudev \ + +kmod-itco-wdt \ + +kmod-crypto-manager \ + +kmod-crypto-sha1 \ + +kmod-crypto-sha256 \ + +kmod-crypto-sha512 \ + +kmod-crypto-cbc \ + +kmod-crypto-qat-c3xxx \ + +kmod-crypto-qat-usdm \ + +kmod-crypto-qat-common \ + +kmod-crypto-qat-api + USERID:=qat=555:qat=555 +endef + +define Package/quickassist-c3xxx/description + Intel Quick Assist v1.7 drivers and utilities for c3xxx series SoCs +endef + +define Package/quickassist-c3xxx/config + source "$(SOURCE)/Config.kernel" + source "$(SOURCE)/Config.in" + config quickassist-c3xxx-enabled + bool + default y if PACKAGE_quickassist-c3xxx + default n +endef + +define KernelPackage/crypto-qat-c3xxx + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Technology Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_OOT)/drivers/crypto/qat/qat_c3xxx/qat_c3xxx.ko +endef + +define KernelPackage/crypto-qat-c3xxx/description + Kernel driver for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-common + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Common Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + +kmod-crypto-authenc \ + +kmod-crypto-kpp + FILES:=$(QAT_OOT)/drivers/crypto/qat/qat_common/intel_qat.ko +endef + +define KernelPackage/crypto-qat-common/description + Kernel driver shared layer for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-common/config + depends on quickassist-c3xxx-enabled +endef + +define KernelPackage/crypto-qat-api + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Kernel API + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_BUILD)/qat_api.ko +endef + +define KernelPackage/crypto-qat-api/description + Kernel API for Intel Quick Assist Technology c3xxx +endef + +define KernelPackage/crypto-qat-usdm + SUBMENU:=Cryptographic API modules + TITLE:=Intel Quick Assist Pinned Memory Driver + DEPENDS:= \ + $(QAT_DEFAULT_DEPENDS) \ + kmod-crypto-qat-common + FILES:=$(QAT_BUILD)/usdm_drv.ko +endef + +define KernelPackage/crypto-qat-usdm/description + Contiguous pinned memory driver for Intel Quick Assist Technology +endef + +ICP_ARCH = x86_64 +MAKE_PATH = quickassist + +QAT_CONFIG += $(if $(CONFIG_QAT_DEBUG) ,ICP_DEBUG="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_STATS) ,DISABLE_STATS="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_LOG_SYSLOG) ,ICP_LOG_SYSLOG="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_PARAM_CHECK) ,ICP_PARAM_CHECK="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_NONBLOCKING_PARTIALS) ,ICP_NONBLOCKING_PARTIALS_PERFORM="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_ONLY) ,ICP_DC_ONLY="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_ONLY) ,DO_CRYPTO="0",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_SYM_ONLY) ,ICP_DC_SYM_ONLY_AM="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DC_COUNTER_ERROR) ,ICP_DC_RETURN_COUNTERS_ON_ERROR="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_INLINE) ,ICP_DISABLE_INLINE="1",) +QAT_CONFIG += $(if $(CONFIG_QAT_HB_FAIL) ,ICP_HB_FAIL_SYM="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_COEXIST) ,QAT_COEXISTENCE="y",) +QAT_CONFIG += $(if $(CONFIG_QAT_LKCF) ,QAT_NO_LKCF="n",) +QAT_CONFIG += $(if $(CONFIG_QAT_DISABLE_STRICT) ,CNV_STRICT_MODE="1",) +QAT_CONFIG += $(if $(CONFIG_PKG_CC_STACKPROTECTOR_NONE) ,ICP_DEFENSES_ENABLED="n",ICP_DEFENSES_ENABLED="y") + +MAKE_VARS += ICP_ROOT="$(PKG_BUILD_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + CXX="$(TARGET_CXX)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + KERNEL_SOURCE_DIR="$(QAT_OOT)" \ + KDIR="$(LINUX_DIR)" \ + MACHINE="$(ICP_ARCH)" \ + USE_OPENSSL="1" \ + ICP_BUILD_OUTPUT="$(QAT_BUILD)" \ + ICP_ENV_DIR="$(QAT_ENV)" \ + ICP_BUILDSYSTEM_PATH="$(QAT_BLDSYS)" \ + ICP_TOOLS_TARGET="accelcomp" \ + $(QAT_CONFIG) \ + ICP_KAPI_M="1" \ + ICP_CORE="ia" \ + ICP_OS="linux_2.6" \ + ICP_ARCH_USER="$(ICP_ARCH)" \ + ICP_DEFENSES_ENABLED="n" \ + LIB_SHARED_FLAGS="-L $(STAGING_DIR)/lib -L $(STAGING_DIR)/usr/lib" \ + LD_LIBRARY_PATH="$(PKG_BUILD_DIR)/build" + +# ICP_DEFENSES_ENABLED="$(ICP_DEFENSES_ENABLED)" \ + +define Build/Prepare + (mkdir -p '$(PKG_BUILD_DIR)' && zcat '$(DL_DIR)/$(PKG_SOURCE)' | tar -C '$(PKG_BUILD_DIR)' -xf -) + $(Build/Patch) +endef + +define Build/Configure + # The shipped configure script is hopelessly broken for cross compilation environments +endef + +define Build/Compile + @echo "QAT Build Configuration: $(QAT_CONFIG)" + $(call Build/Compile/Default, -C $(QAT_OOT)) + $(call Build/Compile/Default, lac_kernel lac_user) + $(call Build/Compile/Default, -C $(QAT_ADF)) +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/icp/quickassist + $(INSTALL_DIR) $(1)/usr/icp/build + $(CP) $(PKG_BUILD_DIR)/build/lib*.{a,so*} $(1)/usr/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/include/{*.h,dc,lac} $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist/lookaside/access_layer/include/*.h $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/quickassist $(1)/usr/icp + $(CP) $(PKG_BUILD_DIR)/build $(1)/usr/icp +endef + +define Package/quickassist-c3xxx/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_DIR) $(1)/etc/hotplug.d + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(INSTALL_DIR) $(1)/lib/firmware + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT1.7/config + $(CP) $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl/conf_files/c3xxx* $(1)/usr/share/quickassist/QAT1.7/config + $(CP) $(PKG_BUILD_DIR)/quickassist/utilities/adf_ctl/adf_ctl $(1)/usr/sbin/adf_ctl + $(CP) $(PKG_BUILD_DIR)/build/*.so* $(1)/lib/ + $(CP) $(PKG_BUILD_DIR)/quickassist/qat/fw/qat_c3xxx* $(1)/lib/firmware/ + $(CP) ./files/qat.init $(1)/etc/init.d/qat + $(CP) ./files/hotplug.d $(1)/etc + $(CP) ./files/sysctl.d $(1)/etc + $(CP) ./files/c3xxx_dev0.conf $(1)/etc/c3xxx_dev0.conf + $(CP) ./files/c3xxx_dev0.conf.multi $(1)/etc/c3xxx_dev0.conf.multi +endef + +define Package/quickassist-c3xxx/postinst +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +[ "$${PKG_UPGRADE}" = "1" ] && exit 0 +sysctl -p /etc/sysctl.d/12-hugepages.conf +/etc/init.d/qat enable +exit 0 +endef + +define Package/quickassist-c3xxx/prerm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] && exit 0 +/etc/init.d/qat stop +exit 0 +endef + +$(eval $(call BuildPackage,quickassist-c3xxx)) +$(eval $(call KernelPackage,crypto-qat-c3xxx)) +$(eval $(call KernelPackage,crypto-qat-common)) +$(eval $(call KernelPackage,crypto-qat-api)) +$(eval $(call KernelPackage,crypto-qat-usdm)) diff --git a/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf new file mode 100644 index 000000000..1e68e9a63 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf @@ -0,0 +1,121 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +################################################################ +[GENERAL] +ServicesEnabled = cy + +# Set the service profile to determine available features +# ===================================================================== +# DEFAULT CRYPTO COMPRESSION CUSTOM1 +# Asymmetric Crypto * * * +# Symmetric Crypto * * * +# MGF KeyGen * * +# SSL/TLS KeyGen * * * +# HKDF * * +# Compression * * * +# Decompression (stateless) * * * +# Decompression (stateful) * * +# Service Chaining * +# Device Utilization * * +# Rate Limiting * * +# ===================================================================== +ServicesProfile = DEFAULT + +ConfigVersion = 2 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 +NumberDcInstances = 0 + +############################################## +# User Process Instance Section +############################################## +[SHIM] +NumberCyInstances = 1 +NumberDcInstances = 0 +NumProcesses = 32 +LimitDevAccess = 1 + +# Crypto - User instance #0 +Cy0Name = "UserCY0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi new file mode 100644 index 000000000..d69bbe241 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/c3xxx_dev0.conf.multi @@ -0,0 +1,127 @@ +################################################################ +# This file is provided under a dual BSD/GPLv2 license. When using or +# redistributing this file, you may do so under either license. +# +# GPL LICENSE SUMMARY +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. +# The full GNU General Public License is included in this distribution +# in the file called LICENSE.GPL. +# +# Contact Information: +# Intel Corporation +# +# BSD LICENSE +# +# Copyright(c) 2007-2020 Intel Corporation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# +################################################################ +[GENERAL] +ServicesEnabled = cy + +# Set the service profile to determine available features +# ===================================================================== +# DEFAULT CRYPTO COMPRESSION CUSTOM1 +# Asymmetric Crypto * * * +# Symmetric Crypto * * * +# MGF KeyGen * * +# SSL/TLS KeyGen * * * +# HKDF * * +# Compression * * * +# Decompression (stateless) * * * +# Decompression (stateful) * * +# Service Chaining * +# Device Utilization * * +# Rate Limiting * * +# ===================================================================== +ServicesProfile = DEFAULT + +ConfigVersion = 2 + +#Default values for number of concurrent requests*/ +CyNumConcurrentSymRequests = 512 +CyNumConcurrentAsymRequests = 64 + +#Statistics, valid values: 1,0 +statsGeneral = 1 +statsDh = 1 +statsDrbg = 1 +statsDsa = 1 +statsEcc = 1 +statsKeyGen = 1 +statsDc = 1 +statsLn = 1 +statsPrime = 1 +statsRsa = 1 +statsSym = 1 + +# This flag is to enable device auto reset on heartbeat error +AutoResetOnError = 0 + +############################################## +# Kernel Instances Section +############################################## +[KERNEL] +NumberCyInstances = 0 +NumberDcInstances = 0 + +############################################## +# User Process Instance Section +############################################## +[SHIM] +NumberCyInstances = 2 +NumberDcInstances = 0 +NumProcesses = 4 +LimitDevAccess = 0 + +# Crypto - User instance #0 +Cy0Name = "UserCY0" +Cy0IsPolled = 1 +# List of core affinities +Cy0CoreAffinity = 0 + +# Crypto - User instance #1 +Cy1Name = "UserCY1" +Cy1IsPolled = 1 +# List of core affinities +Cy1CoreAffinity = 0 diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm new file mode 100755 index 000000000..c6b2375ad --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/module/01-usdm @@ -0,0 +1,32 @@ +#!/bin/sh + +HUGE_PAGE_DIR="/dev/hugepages" + +[ "$DEVICENAME" != "usdm_drv" ] && exit 0 + +[ "$ACTION" == "add" ] && { + + if [ -d ${HUGE_PAGE_DIR} ]; then + + mkdir ${HUGE_PAGE_DIR}/qat 2> /dev/null + + if [ $? -ne 0]; then + logger -t "quickassist(usdm_drv): error creating ${HUGE_PAGE_DIR}/qat" + else + chgrp qat ${HUGE_PAGE_DIR}/qat + chmod 0770 ${HUGE_PAGE_DIR}/qat + fi + + else + logger -t "quickassist(usdm_drv): ${HUGE_PAGE_DIR} not found" + exit 1 + fi + + +} + +[ "$ACTION" == "remove" ] && { + + rmdir ${HUGE_PAGE_DIR}/qat + +} diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl new file mode 100644 index 000000000..565b619c5 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_adf_ctl/01-qat_adf_ctl @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "qat_adf_ctl" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/qat_adf_ctl +chmod 0660 /dev/qat_adf_ctl + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes new file mode 100644 index 000000000..2b6d0fac2 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/qat_dev_processes/01-qat_dev_processes @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "qat_dev_processes" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/qat_dev_processes +chmod 0660 /dev/qat_dev_processes + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio new file mode 100644 index 000000000..fb4ae8335 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/uio/01-uio @@ -0,0 +1,7 @@ +#!/bin/sh + +if [ "$ACTION" != "add" ] && [ "$MAJOR" != "249" ]; then exit 0; fi + +chgrp qat /dev/${DEVICENAME} +chmod 0660 /dev/${DEVICENAME} + diff --git a/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm new file mode 100644 index 000000000..79216d7f7 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/hotplug.d/usdm_drv/01-usdm @@ -0,0 +1,8 @@ +#!/bin/sh + +if [ "$DEVICENAME" != "usdm_drv" ] && [ "$ACTION" != "add" ]; then exit 0; fi + +chgrp qat /dev/usdm_drv +chmod 0660 /dev/usdm_drv + + diff --git a/package/qat/firmware/quickassist-c3xxx/files/qat.init b/package/qat/firmware/quickassist-c3xxx/files/qat.init new file mode 100755 index 000000000..3fffd4c21 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/qat.init @@ -0,0 +1,175 @@ +#!/bin/sh /etc/rc.common + +################################################################# + +# qat Start/Stop the Intel QAT. +# + +START=29 +STOP=99 + +ADF_CTL=/usr/sbin/adf_ctl +QAT_GID=200 +INTEL_VENDORID="8086" +C3XX_DEVICE_PCI_ID="19e2" +NUM_C3XXX_DEVICES=$(lspci -n | egrep -c "$INTEL_VENDORID:$C3XX_DEVICE_PCI_ID") +HUGE_PAGE_DIR=/dev/hugepages +HUGE_PAGE_MOUNT=$(mount | grep hugetlbfs | awk '{print $3}') +MAX_HUGE_PAGES=200 +MAX_HUGE_PAGES_PER_PROCESS=10 + +EXTRA_COMMANDS="status" +EXTRA_HELP=" status Show the status of the qat device" + + +qat_started() { + + ${ADF_CTL} status > /dev/null 2>&1 + return $? + +} + + +status() { + + ${ADF_CTL} status + if [ "$?" -ne 0 ] + then + echo "No devices found. Please start the driver using:" + echo "$0 start" + fi + +} + +insert_digest_modules() { + + if [ $(lsmod | grep -c "sha512") == 0 ]; then + + if [ $(cat /proc/kallsyms |grep -c sha512_) == 0 ]; then + modprobe sha512_ssse3 + else + echo "$0 no sha512_ssse3 module to load" + return 1 + fi + + fi + + if [ $(lsmod | grep -c "sha256") == 0 ]; then + + if [ $(cat /proc/kallsyms |grep -c sha256_) == 0 ]; then + modprobe sha256_ssse3 + else + echo "$0 no sha256_ssse3 module to load" + return 1 + fi + + fi + + return 0 + +} + +mount_hugetlbfs() { + + if [ "${HUGE_PAGE_MOUNT}" != "${HUGE_PAGE_DIR}" ]; then + + [ ! -d ${HUGE_PAGE_DIR} ] && mkdir ${HUGE_PAGE_DIR} + + mount -t hugetlbfs hugetlbfs ${HUGE_PAGE_DIR} -o mode=1770 -o gid=${QAT_GID} + + if [ $? -ne 0 ]; then + echo "$0: error mounting hugetlbfs on ${HUGE_PAGE_DIR}" + return 1 + fi + + fi + + return 0 + +} + +insert_modules() { + + # common functions kernel module + + if [ $(lsmod | grep "intel_qat" | wc -l) == "0" ]; then + modprobe intel_qat + fi + + [ $? -ne 0 ] && return 1 + + # contiguous pinned memory driver + # requires huge pages support in the kernel + + if [ $(lsmod | grep "usdm_drv" | wc -l) == "0" ]; then + modprobe usdm_drv max_huge_pages=${MAX_HUGE_PAGES} max_huge_pages_per_process=${MAX_HUGE_PAGES_PER_PROCESS} + fi + + [ $? -ne 0 ] && return 1 + + # qat device driver + + if [ $(lsmod | grep "qat_c3xxx" | wc -l) == "0" ]; then + modprobe qat_c3xxx + fi + + [ $? -ne 0 ] && return 1 + + # qat kernel api + + if [ $(lsmod | grep "qat_api" | wc -l) == "0" ]; then + modprobe qat_api + fi + + return $? + +} + +start() { + + /sbin/depmod -a 2> /dev/null + + qat_started + + if [ $? -ne 0 ]; then + + insert_digest_modules && [ $? -eq 0 ] && mount_hugetlbfs + + if [ $? -eq 0 ]; then + + if [ ${NUM_C3XXX_DEVICES} != 0 ]; then + insert_modules + [ $? -eq 0 ] && ${ADF_CTL} restart + fi + + fi + + else echo "QAT already started $?"; fi + + ${ADF_CTL} status + +} + +stop() { + + qat_started + + if [ $? -eq 0 ]; then + + ${ADF_CTL} down + rmmod usdm_drv + rmmod qat_api + rmmod qat_c3xxx + rmmod intel_qat + umount ${HUGE_PAGE_DIR} + + fi + +} + +restart() { + + ${ADF_CTL} restart + +} + diff --git a/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf b/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf new file mode 100644 index 000000000..2fdeb45bf --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/files/sysctl.d/12-hugepages.conf @@ -0,0 +1,5 @@ +# setup huge page maximums +# default size is 2MB + +vm.nr_hugepages=256 +vm.hugetlb_shm_group=200 diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch b/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch new file mode 100644 index 000000000..4595a69cd --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0001-remove-host-dependent-stack-protection-check.patch @@ -0,0 +1,15 @@ +--- a/quickassist/build_system/build_files/env_files/environment.mk ++++ b/quickassist/build_system/build_files/env_files/environment.mk +@@ -59,11 +59,7 @@ DIRECT_PATH=$(ICP_ROOT)/quickassist/look + KERNEL_PATH=$(ICP_ROOT)/quickassist/lookaside/access_layer/src/qat_kernel/ + CMN_MEM_PATH=$(ICP_ROOT)/quickassist/utilities/libusdm_drv + ICP_DEFENSES_ENABLED ?= y +-ifeq ($(shell cat /proc/kallsyms | grep -w "__stack_chk_fail" | wc -l), 1) +-KERNEL_DEFENSES_STACK_PROTECTION = y +-else +-KERNEL_DEFENSES_STACK_PROTECTION = n +-endif ++KERNEL_DEFENSES_STACK_PROTECTION ?= n + + #---------------------------------------------------------------------- + # ADF paths diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch b/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch new file mode 100644 index 000000000..177d15fdb --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0002-remove-host-include-paths.patch @@ -0,0 +1,14 @@ +Index: quickassist-c3xxx-1.7.L.4.13.0-00009/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk +=================================================================== +--- quickassist-c3xxx-1.7.L.4.13.0-00009.orig/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk ++++ quickassist-c3xxx-1.7.L.4.13.0-00009/quickassist/build_system/build_files/env_files/linux_2.6_user_space.mk +@@ -46,8 +46,7 @@ + # + #------------------------------------------------------------- + +-INCLUDES+=-I/usr/include \ +- -I$(API_DIR) \ ++INCLUDES+=-I$(API_DIR) \ + -I$(ADF_CMN_DIR) \ + -I$(OSAL_DIR)/include \ + -I$(OSAL_DIR)/src/linux/user_space/include diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0003-OsalServices-musl-bits-time.patch b/package/qat/firmware/quickassist-c3xxx/patches/0003-OsalServices-musl-bits-time.patch new file mode 100644 index 000000000..7d62a3134 --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0003-OsalServices-musl-bits-time.patch @@ -0,0 +1,13 @@ +Index: quickassist-c3xxx-1.7/quickassist/utilities/osal/src/linux/user_space/OsalServices.c +=================================================================== +--- quickassist-c3xxx-1.7.orig/quickassist/utilities/osal/src/linux/user_space/OsalServices.c ++++ quickassist-c3xxx-1.7/quickassist/utilities/osal/src/linux/user_space/OsalServices.c +@@ -42,7 +42,7 @@ + #define __STDC_WANT_LIB_EXT1__ 1 + #include + #include +-#ifdef __linux__ ++#if defined(__linux__) && defined(__GLIBC__) + #include + #include + #endif diff --git a/package/qat/firmware/quickassist-c3xxx/patches/0004-musl-PAGE_SIZE.patch b/package/qat/firmware/quickassist-c3xxx/patches/0004-musl-PAGE_SIZE.patch new file mode 100644 index 000000000..1ffaa88ad --- /dev/null +++ b/package/qat/firmware/quickassist-c3xxx/patches/0004-musl-PAGE_SIZE.patch @@ -0,0 +1,14 @@ +Index: quickassist-c3xxx-1.7/quickassist/utilities/libusdm_drv/linux/user_space/qae_page_table.h +=================================================================== +--- quickassist-c3xxx-1.7.orig/quickassist/utilities/libusdm_drv/linux/user_space/qae_page_table.h ++++ quickassist-c3xxx-1.7/quickassist/utilities/libusdm_drv/linux/user_space/qae_page_table.h +@@ -82,7 +82,9 @@ + #endif + + #ifndef __FreeBSD__ /* FreeBSD, already defined in machine param.h */ ++#if defined(__GLIBC__) + #define PAGE_SIZE (0x1000) ++#endif + #define PAGE_SHIFT (12) + #endif + diff --git a/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile b/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile new file mode 100644 index 000000000..fcca68a22 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crc32-pclmul/Makefile @@ -0,0 +1,49 @@ + +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crc32-pclmul +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-crc32-pclmul + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRC32 hardware acceleration (PCLMULDQ) + DEPENDS:=+kmod-crypto-hash +kmod-crypto-crc32 @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRC32_PCLMUL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crc32-pclmul.ko + AUTOLOAD:=$(call AutoLoad,09,crc32-pclmul) +endef + +define KernelPackage/$(KMOD_NAME)/description + From Intel Westmere and AMD Bulldozer processor with SSE4.2 and PCLMULQDQ supported, the processor will support CRC32 PCLMULQDQ + implementation using hardware accelerated PCLMULQDQ instruction. This option will create 'crc32-pclmul' module, which will enable + any routine to use the CRC-32-IEEE 802.3 checksum and gain better performance as compared with the table implementation +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile b/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile new file mode 100644 index 000000000..a3d2700ce --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crc32c-intel/Makefile @@ -0,0 +1,48 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crc32c-intel +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-crc32c-intel + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRC32c hardware acceleration (SSE4.2) + DEPENDS:=+kmod-crypto-hash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRC32C_INTEL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crc32c-intel.ko + AUTOLOAD:=$(call AutoLoad,09,crc32-intel) +endef + +define KernelPackage/$(KMOD_NAME)/description + In Intel processor with SSE4.2 supported, the processor will support CRC32C implementation using hardware accelerated CRC32 instruction. + This option will create 'crc32c-intel' module, which will enable any routine to use the hardware accelerated CRC32 instruction + Module will be crc32c-intel +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile b/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile new file mode 100644 index 000000000..f6a237f63 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-crct10dif-pclmu/Makefile @@ -0,0 +1,47 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-crct10dif-pclmu +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/$(KMOD_NAME) + SUBMENU:=$(CRYPTO_MENU) + TITLE:=CRCT10DIF hardware acceleration + DEPENDS:=+kmod-crypto-hash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_CRCT10DIF_PCLMUL + FILES:=$(LINUX_DIR)/arch/x86/crypto/crct10dif-pclmul.ko + AUTOLOAD:=$(call AutoLoad,09,crct10dif-pclmul) +endef + +define KernelPackage/$(KMOD_NAME)/description + CRC T10 Data Integrity Field computation is being cast as a crypto transform. + This allows for faster crc t10 diff transforms to be used if they are available. +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile b/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile new file mode 100644 index 000000000..02d7371be --- /dev/null +++ b/package/qat/kernel/kmod-crypto-ghash-clmulni/Makefile @@ -0,0 +1,46 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-ghash-clmulni +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-ghash-clmulni + SUBMENU:=$(CRYPTO_MENU) + TITLE:=GHASH digest hardware acceleration + DEPENDS:=+kmod-crypto-ghash @TARGET_x86_64 + KCONFIG:=CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL + FILES:=$(LINUX_DIR)/arch/x86/crypto/ghash-clmulni-intel.ko + AUTOLOAD:=$(call AutoLoad,09,ghash-clmulni-intel) +endef + +define KernelPackage/$(KMOD_NAME)/description + GHASH is message digest algorithm for GCM (Galois/Counter Mode). The implementation is accelerated by CLMUL-NI of Intel. +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile b/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile new file mode 100644 index 000000000..7e453e06d --- /dev/null +++ b/package/qat/kernel/kmod-crypto-misc-cxxxx/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-misc-cxxxx +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-misc-cxxxx + SUBMENU:=$(CRYPTO_MENU) + HIDDEN:=1 + TITLE:=crypto-misc-cxxxx + DEPENDS:=kmod-crypto-misc @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-misc) + FILES:= \ + $(LINUX_DIR)/arch/x86/crypto/camellia-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/blowfish-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-x86_64-3way.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-sse2-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/camellia-aesni-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/cast5-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/cast6-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/twofish-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-avx-x86_64.ko \ + $(LINUX_DIR)/arch/x86/crypto/camellia-aesni-avx2.ko \ + $(LINUX_DIR)/arch/x86/crypto/serpent-avx2.ko \ + $(LINUX_DIR)/crypto/ablk_helper.ko@lt4.17 + AUTOLOAD+= $(call AutoLoad,10,camellia-x86_64 \ + camellia-aesni-avx-x86_64 camellia-aesni-avx2 cast5-avx-x86_64 \ + cast6-avx-x86_64 twofish-x86_64 twofish-x86_64-3way \ + twofish-avx-x86_64 blowfish-x86_64 serpent-avx-x86_64 serpent-avx2) +endef + +define KernelPackage/$(KMOD_NAME)/description + Camellia, Camellia-AESNI, Blowfish, Twofish, Serpent, Serpent SSE2, Serpent AVX2, Cast5, Cast6 +endef + +$(eval $(call KernelPackage,$(KMOD_NAME))) + diff --git a/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile b/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile new file mode 100644 index 000000000..6c6547fd2 --- /dev/null +++ b/package/qat/kernel/kmod-crypto-sha-cxxxx/Makefile @@ -0,0 +1,66 @@ +# +# Copyright (C) 2019 OpenWrt.org and dl12345@github.com +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +KMOD_NAME:=crypto-sha-cxxxx +PKG_NAME:=kmod-$(KMOD_NAME) +PKG_VERSION:=1.0 +PKG_RELEASE:=1 + +PKG_MAINTAINER:=dl12345 +PKG_LICENSE:=GPL v3 + +include $(INCLUDE_DIR)/kernel.mk +include $(INCLUDE_DIR)/package.mk + +CRYPTO_MENU:=Cryptographic API modules +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define KernelPackage/crypto-sha1-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA1 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha1 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha1) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha1-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha1-ssse3) +endef + +define KernelPackage/crypto-sha256-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA256 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha256 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha256) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha256-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha256-ssse3) +endef + +define KernelPackage/crypto-sha512-cxxxx + SUBMENU:=$(CRYPTO_MENU) + TITLE:=SHA512 x86_64 versions for C2000/C3000 target + HIDDEN:=1 + DEPENDS:=kmod-crypto-sha512 @(TARGET_x86_c2xxx||TARGET_x86_c3xxx) + DEFAULT:=y if ((TARGET_x86_c2xxx||TARGET_x86_c3xxx) && PACKAGE_kmod-crypto-sha512) + FILES:=$(LINUX_DIR)/arch/x86/crypto/sha512-ssse3.ko + AUTOLOAD+=$(call AutoLoad,09,sha512-ssse3) +endef + +$(eval $(call KernelPackage,crypto-sha1-cxxxx)) +$(eval $(call KernelPackage,crypto-sha256-cxxxx)) +$(eval $(call KernelPackage,crypto-sha512-cxxxx)) + diff --git a/package/qat/libs/eudev/Config.in b/package/qat/libs/eudev/Config.in new file mode 100644 index 000000000..900741ebf --- /dev/null +++ b/package/qat/libs/eudev/Config.in @@ -0,0 +1,69 @@ +# udev package config + +menu "Configuration" + depends on PACKAGE_eudev + +config EUDEV_EXTRA_ata_id + bool "Install eudev ata_id callout" + default y + help + ata_id - udev callout to read product/serial number + from ATA drives + +config EUDEV_EXTRA_blkid + bool "Use blkid to identify block devices" + default y + help + blkid - make use of libblkid to identify block devices + +config EUDEV_EXTRA_cdrom_id + bool "Install eudev cdrom_id callout" + default y + help + cdrom_id - udev callout to determine the capabilities + of optical drives and media + +config EUDEV_EXTRA_collect + bool "Install eudev collect" + default n + help + Adds ID to the list governed by + +config EUDEV_EXTRA_input_id + bool "Install input_id callout" + default y + help + input_id - udev callout to classify input devices + +config EUDEV_EXTRA_kmod + bool "Use kmod for loading kernel modules" + default n + help + kmod - make use of kmod to load kernel modules on demand + +config EUDEV_EXTRA_mtd_probe + bool "Install mtd_probe callout" + default y + help + mtd_probe - udev callout to probe mtd devices + +config EUDEV_EXTRA_rule_generator + bool "Install (legacy) eudev rule_generator" + default n + help + Install (legacy) eudev rule_generator + +config EUDEV_EXTRA_scsi_id + bool "Install eudev scsi_id callout" + default y + help + scsi_id - retrieve and generate a unique SCSI identifier + +config EUDEV_EXTRA_v4l_id + bool "Install eudev v4l_id callout" + default y + help + v4l_id - udev callout to identify Video4Linux devices + + +endmenu diff --git a/package/qat/libs/eudev/Makefile b/package/qat/libs/eudev/Makefile new file mode 100644 index 000000000..a368d2335 --- /dev/null +++ b/package/qat/libs/eudev/Makefile @@ -0,0 +1,88 @@ +# +# Copyright (C) 2006-2008 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=eudev +PKG_VERSION:=3.2.9 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://dev.gentoo.org/~blueness/eudev/ +PKG_HASH:=89618619084a19e1451d373c43f141b469c9fd09767973d73dd268b92074d4fc +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +PKG_BUILD_DEPENDS:=gperf/host +PKG_FIXUP:=autoreconf +PKG_INSTALL=1 + +define Package/libeudev + SECTION:=libs + CATEGORY:=Libraries + TITLE:=Dynamic device management subsystem + URL:=https://wiki.gentoo.org/wiki/Project:Eudev + MAINTAINER:=Ian Cooper + PROVIDES:=libudev + CONFLICTS:=libudev-zero udev +endef + +define Package/eudev + SECTION:=Libs + CATEGORY:=Libraries + TITLE:=Dynamic device management subsystem + URL:=https://wiki.gentoo.org/wiki/Project:Eudev + MAINTAINER:=Ian Cooper + MENU:=1 + DEPENDS:=+EUDEV_EXTRA_blkid:libblkid +EUDEV_EXTRA_kmod:libkmod +librt +libeudev +endef + +define Package/eudev/description +Eudev is the Gentoo Linux port of udev. This implementation installs only the libraries +and a udevmonitor binary. This allows packages dependent on libudev to be compiled and +run on OpenWrt. The udevmonitor binary can be used to see what events are tiggered so +that an appropriate hotplug handler script can be installed. +endef + +define Package/eudev/config + source "$(SOURCE)/Config.in" +endef + +CONFIGURE_ARGS += \ + --prefix=/usr --exec-prefix= --sysconfdir=/etc \ + --libexecdir=/lib/udev --sbindir=/sbin \ + --disable-hwdb --disable-introspection --disable-manpages \ + --disable-selinux \ + $(if $(CONFIG_EUDEV_EXTRA_blkid),--enable-blkid,--disable-blkid) \ + $(if $(CONFIG_EUDEV_EXTRA_kmod),--enable-kmod,--disable-kmod) + + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/libudev.h $(1)/usr/include + $(INSTALL_DIR) $(1)/usr/share/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/usr/share/pkgconfig/udev.pc $(1)/usr/share/pkgconfig + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.so* $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.a $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/lib/pkgconfig + $(CP) $(PKG_INSTALL_DIR)/lib/pkgconfig/libudev.pc $(1)/usr/lib/pkgconfig +endef + +define Package/libeudev/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/lib/libudev.so* $(1)/usr/lib +endef + +define Package/eudev/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/udevadm $(1)/sbin/udevadm +endef + +$(eval $(call BuildPackage,eudev)) +$(eval $(call BuildPackage,libeudev)) diff --git a/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch b/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch new file mode 100644 index 000000000..deac91589 --- /dev/null +++ b/package/qat/libs/eudev/patches/0001-mtd_probe-uses-stdint_h.patch @@ -0,0 +1,12 @@ +Index: eudev-3.2.9/src/mtd_probe/mtd_probe.h +=================================================================== +--- eudev-3.2.9.orig/src/mtd_probe/mtd_probe.h ++++ eudev-3.2.9/src/mtd_probe/mtd_probe.h +@@ -20,6 +20,7 @@ + #pragma once + + #include ++#include + + #include "macro.h" + diff --git a/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch b/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch new file mode 100644 index 000000000..e64670007 --- /dev/null +++ b/package/qat/libs/eudev/patches/0002-udevadm-cutdown.patch @@ -0,0 +1,18 @@ +Index: eudev-3.2.9/src/udev/udevadm.c +=================================================================== +--- eudev-3.2.9.orig/src/udev/udevadm.c ++++ eudev-3.2.9/src/udev/udevadm.c +@@ -45,13 +45,7 @@ static const struct udevadm_cmd udevadm_ + + static const struct udevadm_cmd *udevadm_cmds[] = { + &udevadm_info, +- &udevadm_trigger, +- &udevadm_settle, +- &udevadm_control, + &udevadm_monitor, +- &udevadm_hwdb, +- &udevadm_test, +- &udevadm_test_builtin, + &udevadm_version, + &udevadm_help, + }; diff --git a/package/qat/libs/openssl-qat/Config.in b/package/qat/libs/openssl-qat/Config.in new file mode 100644 index 000000000..e3bd39381 --- /dev/null +++ b/package/qat/libs/openssl-qat/Config.in @@ -0,0 +1,160 @@ +menu "Configuration" + depends on TARGET_x86_64 + + choice + prompt "Platform" + default QAT_NONE + config QAT_NONE + bool "None (Default)" + config QAT_C2XXX + bool "c2xxx - Rangeley" + depends on LINUX_4_14 + select PACKAGE_quickassist-c2xxx + select PACKAGE_kmod-crypto-qat-c2xxx + select PACKAGE_kmod-crypto-qat-c2xxx-usdm + config QAT_C3XXX + bool "c3xxx - Denverton" + select PACKAGE_quickassist-c3xxx + select PACKAGE_kmod-crypto-qat-c3xxx + select PACKAGE_kmod-crypto-qat-common + select PACKAGE_kmod-crypto-qat-usdm + + endchoice + + config QAT_ENGINE_DISABLE_RSA + bool + default n + prompt "Disable QAT RSA offload" + + config QAT_ENGINE_DISABLE_DSA + bool + default n + prompt "Disable QAT DSA offload" + + config QAT_ENGINE_DISABLE_DH + bool + default n + prompt "Disable QAT DH offload" + + config QAT_ENGINE_DISABLE_EDSA + bool + default n + prompt "Disable QAT ECDSA offload" + + config QAT_ENGINE_DISABLE_CIPHERS + bool + default y + prompt "Disable QAT chained cipher offload" + help + Offload of chained ciphers performs significantly worse than CPU + based chained ciphers. Strongly recommended to keep this disabled + + config QAT_ENGINE_DISABLE_HKDF + bool + default y + prompt "Disable QAT HKDF offload" + help + Disable QAT HKDF offload + + config QAT_ENGINE_ENABLE_GCM_CIPHERS + bool + default n + prompt "Enable QAT GCM offload" + help + Enable QAT GCM offload + + config QAT_ENGINE_ENABLE_SMALL_PACKET + bool + default n + prompt "Enable offload of small packet cipher operations" + help + This is generally a bad idea from a performance point of view since + there is a penalty for transfer of the data across the pci bus to the + accelerator that makes it faster for small packet operations using + only cpu resources and not QAT offloading (generally < 4k bufsize) + + config QAT_ENGINE_ENABLE_WARNINGS + bool + default n + prompt "Enable warnings to aid in debugging" + help + WARNING: never leave on in a production environment as it may output + private key informtion to the logs and it may introduce side-channel + timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_DEBUG + bool + default n + prompt "Enable debug output" + help + WARNING: never leave on in a production environment as it may output + private key informtion to the logs and it may introduce side-channel + timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_QAT_MEM_WARNINGS + bool + default n + prompt "Enable warnings from the userspace memory management code" + help + WARNING: This option should never be left on in a production + environment as it may introduce side channel timing attack + vulnerabilities + + config QAT_ENGINE_ENABLE_MEM_DEBUG + bool + default n + prompt "Enable debug output from userspace memory management (very verbose)" + help + This will also enable the QAT_MEM warning messages. This option + produces quite verbose output hence why it is separate to the + standard debug. + + WARNING: This option should never be enabled in a production environment + as it may output private key information to the console/logs and may + also introduce side channel timing attack vulnerabilities + + config QAT_ENGINE_ENABLE_MULTITHREAD + bool + default n + prompt "Optimize for multi-threaded use" + help + This alternative method will give improved performance in a + multi-threaded environment by making the slab pools thread + local to avoid locking between threads. Although this can + give better performance there are several drawbacks such as + the memory slabs will be utilized less efficiently, and you + cannot allocate in one thread and free in another thread. + Running in this mode DOES NOT support processes that fork + + config QAT_ENGINE_DISABLE_LENSTRA + bool + default n + prompt "Disable protection against Lenstra attack (CVE-2017-5681)" + help + The RSA-CRT implementation in the Intel(R) QAT OpenSSL* Engine for + OpenSSL* versions prior to v0.5.19 may allow remote attackers to + obtain private RSA keys by conducting a Lenstra side-channel attack. + From version v0.5.19 onward, protection against this form of attack + is effected by performing a Verify/Encrypt operation after the Sign/Decrypt + operation, and if a failure is detected then re-running the Sign/Decrypt + operation using the CPU. However, future releases of Intel(R) QAT + driver code or firmware may effect this protection instead, in which + case the Intel(R) QAT OpenSSL* Engine code-based protection would no + longer be required and this configuration option should then be selected. + + config QAT_ENGINE_DISABLE_AUTOINIT_ONFORK + bool + default y + prompt "Disable auto engine init on fork" + help + Disable the engine from being initialized automatically following a + fork operation. This is useful in a situation where you want to tightly + control how many instances are being used for processes. For instance if an + application forks to start a process that does not utilize QAT currently + the default behaviour is for the engine to still automatically get started + in the child using up an engine instance. After using this flag either the + engine needs to be initialized manually using the engine message: + INIT_ENGINE or will automatically get initialized on the first QAT crypto + operation. + +endmenu diff --git a/package/qat/libs/openssl-qat/Makefile b/package/qat/libs/openssl-qat/Makefile new file mode 100644 index 000000000..4d3097569 --- /dev/null +++ b/package/qat/libs/openssl-qat/Makefile @@ -0,0 +1,84 @@ +# +# Copyright (C) Ian Cooper +# +# This is free software, licensed under the GNU General Public License v3. +# +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=openssl-qat +PKG_VERSION:=0.6.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=v${PKG_VERSION}.tar.gz +PKG_SOURCE_URL:=https://github.com/intel/QAT_Engine/archive/refs/tags/ +PKG_HASH:=skip + +PKG_BUILD_DIR:=$(BUILD_DIR)/QAT_Engine-$(PKG_VERSION) +PKG_BUILD_DEPENDS:=openssl +PKG_FIXUP:=autoreconf +PKG_REMOVE_FILES:=autogen.sh + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/openssl-qat + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=SSL + TITLE:=Intel Quick Assist OpenSSL Engine + URL:=https://github.com/intel/QAT_Engine.git + DEPENDS:= \ + @TARGET_x86_64 \ + +libopenssl \ + +(TARGET_x86_64&&QAT_C2XXX):quickassist-c2xxx \ + +(TARGET_x86_64&&QAT_C3XXX):quickassist-c3xxx +endef + +define Package/openssl-qat/description + Intel Quick Assist hardware acceleration engine for OpenSSL +endef + +define Package/openssl-qat/config + source "$(SOURCE)/Config.in" +endef + +#CONFIGURE_ARGS += --with-openssl_install_dir=$(PKG_INSTALL_DIR)/usr +CONFIGURE_ARGS += --prefix=$(PKG_INSTALL_DIR) + +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C3XXX) ,--with-qat_dir=$(KERNEL_BUILD_DIR)/quickassist-c3xxx-1.7) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C2XXX) ,--with-qat_dir=$(KERNEL_BUILD_DIR)/quickassist-c2xxx-1.5) + +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_RSA) ,--disable-qat_rsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_DSA) ,--disable-qat_dsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_DH) ,--disable-qat_dh) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_ECDSA) ,--disable-qat_ecdsa) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_CIPHERS) ,--disable-qat_ciphers) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_PRF) ,--disable-qat_prf) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_HKDF) ,--disable-qat_hkdf) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_GCM_CIPHERS) ,--enable-qat_gcm) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_SMALL_PACKET) ,--enable-qat_small_pkt_offload) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_WARNINGS) ,--enable-qat_warnings) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_DEBUG) ,--enable-qat_debug) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_QAT_MEM_WARNINGS) ,--enable-qat_mem_warnings) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_MEM_DEBUG) ,--enable-qat_mem_debug) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_ENABLE_MULTITHREAD) ,--enable-multi_thread) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_LENSTRA) ,--disable-qat_lenstra_protection) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_ENGINE_DISABLE_AUTOINIT_ONFORK) ,--disable-qat_auto_engine_init_on_fork) +CONFIGURE_ARGS += $(if $(CONFIG_QAT_C2XXX) ,--enable-qat16_driver) + +MAKE_VARS += \ + CROSS_COMPILE="$(KERNEL_CROSS)" \ + KERNEL_SOURCE_ROOT="$(LINUX_DIR)" \ + PATH_AUTOCNF="include/generated/autoconf.h" \ + WITH_ICP_TARGET="1" + +define Package/openssl-qat/install + $(INSTALL_DIR) $(1)/usr/lib/engines-1.1 + $(INSTALL_DIR) $(1)/usr/share/quickassist/QAT_Engine/config + $(CP) $(PKG_BUILD_DIR)/.libs/qatengine.so $(1)/usr/lib/engines-1.1 + $(CP) $(PKG_BUILD_DIR)/qatengine.la $(1)/usr/lib/engines-1.1 + $(CP) $(PKG_BUILD_DIR)/qat/config/c3xxx $(1)/usr/share/quickassist/QAT_Engine/config +endef + +$(eval $(call BuildPackage,openssl-qat)) diff --git a/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch b/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch new file mode 100644 index 000000000..4721e2ef7 --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0001-remove-FORTIFY_SOURCE.patch @@ -0,0 +1,21 @@ +Index: QAT_Engine-0.6.4/configure.ac +=================================================================== +--- QAT_Engine-0.6.4.orig/configure.ac ++++ QAT_Engine-0.6.4/configure.ac +@@ -554,13 +554,13 @@ case "$host_os" in + *linux*) + if test "`cc --version | head -1 | awk '{print $3>=4.9}' 2>/dev/null`" = "1" + then +- AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong -fno-strict-overflow") ++ AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fno-strict-overflow") + else +- AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector -fno-strict-overflow") ++ AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fno-strict-overflow") + fi + ;; + *freebsd*) +- AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -D_FORTIFY_SOURCE=2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong") ++ AC_ARG_WITH(cflags, AS_HELP_STRING(), , cflags="-shared -fPIC -Wall -Wformat -Wformat-security -O2 -fno-delete-null-pointer-checks -fwrapv -fstack-protector-strong") + ;; + *) ;; + esac diff --git a/package/qat/libs/openssl-qat/patches/0002-fix-autoconf-glibc-detection.patch b/package/qat/libs/openssl-qat/patches/0002-fix-autoconf-glibc-detection.patch new file mode 100644 index 000000000..882142958 --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0002-fix-autoconf-glibc-detection.patch @@ -0,0 +1,27 @@ +--- a/.tools/configure.ac ++++ b/.tools/configure.ac +@@ -415,19 +415,19 @@ then + AC_MSG_NOTICE([Enabling writing debug to file]) + fi + +- +-AC_CHECK_PROG(USE_GETCONF, getconf, yes, no) ++AC_CHECK_PROG(USE_LDD, ldd, yes, no) ++AC_CHECK_PROG(USE_HEAD, head, yes, no) + AC_PROG_AWK +-if test $AWK == "gawk" -a $USE_GETCONF == "yes" ++if test $AWK == "gawk" -a $USE_LDD == "yes" -a $USE_HEAD + then + AC_MSG_NOTICE([Getting glibc version ...]) +- if test `getconf GNU_LIBC_VERSION | gawk '{print $2>=2.23?"1":"0"}' 2>/dev/null` == 1 ++ if test `ldd --version | head -1 | gawk '{print $4>=2.23?"1":"0"}' 2>/dev/null` == 1 + then + AC_MSG_NOTICE([glibc version is greater or equal to 2.23 so AVX-512 optimisations are supported.]) + else + AC_MSG_NOTICE([glibc version is less than 2.23 - no AVX-512 optimisation supported.]) + fi +- if test `getconf GNU_LIBC_VERSION | gawk '{print $2<2.17?"1":"0"}' 2>/dev/null` == 1 ++ if test `ldd --version | head -1 | gawk '{print $4<2.17?"1":"0"}' 2>/dev/null` == 1 + then + AC_ARG_WITH(LIBS, AS_HELP_STRING(), , LIBS+="-lrt") + AC_SUBST(LIBS) diff --git a/package/qat/libs/openssl-qat/patches/0003-fix-install-command.patch b/package/qat/libs/openssl-qat/patches/0003-fix-install-command.patch new file mode 100644 index 000000000..7f4971f4a --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0003-fix-install-command.patch @@ -0,0 +1,11 @@ +--- a/.tools/Makefile.am ++++ b/.tools/Makefile.am +@@ -137,7 +137,7 @@ MAKE = make err-files && make + endif + + install-data-am: +- -cp -f $(prefix)/lib/libqat.so $(ENGINE_LIB) ++ cp -L --remove-destination .libs/libqat.so $(ENGINE_LIB) + + err-files: + if QAT_OPENSSL_102 diff --git a/package/qat/libs/openssl-qat/patches/0004-usdm_drv-qat16.patch b/package/qat/libs/openssl-qat/patches/0004-usdm_drv-qat16.patch new file mode 100644 index 000000000..355899ed9 --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0004-usdm_drv-qat16.patch @@ -0,0 +1,11 @@ +--- a/.tools/configure.ac ++++ b/.tools/configure.ac +@@ -533,7 +533,7 @@ then + AC_SUBST(QAT_SHARED_LIB_DEPS_DRIVER) + fi + +-if test "x$enable_qat_contig_mem" != "xyes" -a "x$enable_multi_thread" != "xyes" -a "$enable_qat16_driver" = "xyes" ++if test "x$enable_qat_contig_mem" != "xyes" -a "x$enable_multi_thread" != "xyes" + then + AC_ARG_WITH(QAT_SHARED_LIB_DEPS_QAE_MEM, AS_HELP_STRING(), , QAT_SHARED_LIB_DEPS_QAE_MEM=["-Wl,-rpath,\$(with_usdm_dir) -L\$(with_usdm_dir) -lusdm_drv_s"]) + AC_SUBST(QAT_SHARED_LIB_DEPS_QAE_MEM) diff --git a/package/qat/libs/openssl-qat/patches/0005-musl-GLIBC_PREREQ.patch b/package/qat/libs/openssl-qat/patches/0005-musl-GLIBC_PREREQ.patch new file mode 100644 index 000000000..92cabb53b --- /dev/null +++ b/package/qat/libs/openssl-qat/patches/0005-musl-GLIBC_PREREQ.patch @@ -0,0 +1,15 @@ +Index: openssl-qat-1/e_qat.c +=================================================================== +--- openssl-qat-1.orig/e_qat.c ++++ openssl-qat-1/e_qat.c +@@ -1327,8 +1327,10 @@ static int bind_qat(ENGINE *e, const cha + * configuration as environment variables. + */ + ++#if defined(__GLIBC__) + #if __GLIBC_PREREQ(2, 17) + config_section = secure_getenv("QAT_SECTION_NAME"); ++#endif + #else + config_section = getenv("QAT_SECTION_NAME"); + #endif diff --git a/package/qat/libs/qatzip/Makefile b/package/qat/libs/qatzip/Makefile new file mode 100644 index 000000000..a08755b19 --- /dev/null +++ b/package/qat/libs/qatzip/Makefile @@ -0,0 +1,108 @@ +# +# Copyright (C) DL +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +# +include $(TOPDIR)/rules.mk + +PKG_NAME:=qatzip +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_SOURCE_URL:=https://github.com/intel/QATzip +PKG_SOURCE_PROTO:=git +PKG_SOURCE_DATE:=2020-05-15 +PKG_SOURCE_VERSION:=5abaaf546a479350ada023115c6e3d499db2b363 +PKG_MIRROR_HASH:=17ff33161e7a6b513f90050fb747e0a6f0a74ea3e4e3b1dc10b18e5540adbe9a + +PKG_BUILD_DEPENDS:=openssl +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/kernel.mk + +define Package/libqatzip + SECTION:=libs + CATEGORY:=Libraries + SUBMENU:=Compression + TITLE:=Intel Quick Assist QATzip Compression Library + URL:=https://github.com/intel/QATzip + DEPENDS:= \ + @TARGET_x86_64 \ + +zlib \ + +openssl-qat +endef + +define Package/libqatzip/description + Intel Quick Assist userspace compression library +endef + +define Package/qzip + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Compression + TITLE:=Intel Quick Assist qzip compression utility + URL:=https://github.com/intel/QATzip + DEPENDS:= \ + @TARGET_x86_64 \ + +libqatzip +endef + +define Package/qzip/description + Intel Quick Assist file compression utility +endef + +PKG_BUILD_DEPENDS += $(if $(CONFIG_QAT_C2XXX),quickassist-c2xxx,quickassist-c3xxx) +QAT_DIR=$(KERNEL_BUILD_DIR)/$(if $(CONFIG_QAT_C2XXX),quickassist-c2xxx-1.5,quickassist-c3xxx-1.7)/quickassist + +TARGET_CFLAGS += \ + -I$(QAT_DIR)/include \ + -I$(QAT_DIR)/include/dc \ + -I$(QAT_DIR)/lookaside/access_layer/include \ + -I$(QAT_DIR)/utilities/libusdm_drv \ + -I$(PKG_BUILD_DIR)/include \ + -I$(PKG_BUILD_DIR)/src \ + -DADF_PCI_API \ + -fPIC + +TARGET_LDFLAGS += \ + -L$(QAT_DIR)/build + +MAKE_VARS += \ + QATZIP_LIB_STATIC="libqatzip.a" \ + QATZIP_LIB_SHARED="libqatzip.so" \ + QATZIP_LIB_D="$(PKG_BUILD_DIR)/src" \ + LIBADD="-lqat_s -lusdm_drv_s -lz -lpthread -ludev -lssl" \ + VER="1.0.1" \ + VER_M="1" \ + LN_S="ln -s" + +define Build/Configure +endef + +define Build/Compile + $(call Build/Compile/Default, -C src libqatzip.so) + $(call Build/Compile/Default, -C src libqatzip.a) + $(call Build/Compile/Default, -C utils qzip) +endef + +define Package/InstallDev + $(INSTALL_DIR) $(1)/usr/lib + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_BUILD_DIR)/src/lib*.{a,so*} $(1)/usr/lib/ +endef + +define Package/libqatzip/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_BUILD_DIR)/src/lib*.so* $(1)/usr/lib/ +endef + +define Package/qzip/install + $(INSTALL_DIR) $(1)/usr/bin + $(CP) $(PKG_BUILD_DIR)/utils/qzip $(1)/usr/bin/qzip +endef + +$(eval $(call BuildPackage,libqatzip)) +$(eval $(call BuildPackage,qzip)) diff --git a/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch b/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch new file mode 100644 index 000000000..dbaa66de4 --- /dev/null +++ b/package/qat/libs/qatzip/patches/0001-musl-bits-types.patch @@ -0,0 +1,14 @@ +Index: qatzip-1/src/qatzip.c +=================================================================== +--- qatzip-1.orig/src/qatzip.c ++++ qatzip-1/src/qatzip.c +@@ -40,7 +40,9 @@ + #include + #include + #include ++#if defined(__linux__) && defined(__GLIBC__) + #include ++#endif + #include + #include + #include diff --git a/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch b/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch new file mode 100644 index 000000000..7011acb8a --- /dev/null +++ b/package/qat/libs/qatzip/patches/0002-musl-reopen-stdout.patch @@ -0,0 +1,14 @@ +Index: qatzip-1/utils/qzip.c +=================================================================== +--- qatzip-1.orig/utils/qzip.c ++++ qatzip-1/utils/qzip.c +@@ -776,7 +776,9 @@ int main(int argc, char **argv) + printf("For help, type: qzip -h\n"); + } else { + stream_out = stdout; ++#ifdef __GLIBC___ + stdout = freopen(NULL, "w", stdout); ++#endif + processStream(&g_sess, stdin, stream_out, g_decompress == 0); + } + } else {