fix(packer): AWS images
[csit.git] / fdio.infra.ansible / roles / aws / files / get-vfio-with-wc.sh
1 #!/usr/bin/env bash
2 # Enable WC in VFIO-PCI driver
3 # Tested on:
4 #  * Amazon Linux 2 AMI (HVM), SSD Volume Type - ami-0bb3fad3c0286ebd5
5 #  * Amazon Linux AMI 2018.03.0 (HVM), SSD Volume Type - ami-015232c01a82b847b
6 #  * Red Hat Enterprise Linux 8 (HVM), SSD Volume Type - ami-08f4717d06813bf00
7 #  * Ubuntu Server 20.04 LTS (HVM), SSD Volume Type - ami-06fd8a495a537da8b
8 #  * Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-0823c236601fef765
9
10 set -e
11
12 TMP_DIR="tmp"
13
14 # Kernel modules location:
15 P1="/usr/lib/modules/`uname -r`/kernel/drivers/vfio"
16 P2="/lib/modules/`uname -r`/kernel/drivers/vfio"
17
18 # This may return an error if executed from inside the script
19 set +e
20 RED="$(tput setaf 1)"
21 GREEN="$(tput setaf 2)"
22
23 BOLD="$(tput bold)"
24 NORMAL="$(tput sgr0)"
25 set -e
26
27 function bold {
28         echo -e "${BOLD}${@}${NORMAL}"
29 }
30
31 function err {
32         bold "${RED}ERROR: ${@}"
33 }
34
35 function green {
36         bold "${GREEN}${@}"
37 }
38
39 function get_kernel_version {
40         local ver=$(uname -r | cut -f 1 -d '-')
41         local ver_major=$(echo $ver | cut -f1 -d '.')
42         local ver_minor=$(echo $ver | cut -f2 -d '.')
43         local ver_subminor=$(echo $ver | cut -f3 -d '.')
44
45         printf "%d%02d%04d" "${ver_major}" "${ver_minor}" "${ver_subminor}"
46 }
47
48 function download_kernel_src_yum {
49         echo "Use yum to get the kernel sources"
50
51         bold "\nInstall required applications and kernel headers"
52         yum install -y gcc "kernel-$(uname -r)" "kernel-devel-$(uname -r)" \
53             git make elfutils-libelf-devel patch yum-utils
54         green Done
55
56         # Download kernel source
57         bold "\nDownload kernel source with vfio"
58         yumdownloader --source "kernel-devel-$(uname -r)"
59         rpm2cpio kernel*.src.rpm | cpio -idmv
60         green Done
61
62         rm -f *patches.tar
63         tar xf linux-*.tar*
64         rm -f linux-*.tar* linux-*.patch
65 }
66
67 function download_kernel_src_apt {
68         echo "Use apt-get to get the kernel sources"
69         apt-get -q -y update
70         green Done
71
72         bold "\nInstall required applications"
73         apt-get -q -y install dpkg-dev build-essential git
74         green Done
75
76         bold "\nDownload Linux kernel source with vfio"
77         if ! apt-get -q -y source -t focal linux-image-$(uname -r); then
78                 err "Cannot download Linux kernel source.\nPlease uncomment appropriate 'deb-src' line in the /etc/apt/sources.list file"
79                 exit 1
80         fi
81         green Done
82
83         rm -f linux-*.dsc linux-*.gz
84 }
85
86 function download_kernel_src {
87         bold "[1] Downloading prerequisites..."
88         rm -rf "${TMP_DIR}"
89         mkdir -p "${TMP_DIR}"
90         cd "${TMP_DIR}"
91
92         if apt-get -v >/dev/null 2>/dev/null; then
93                 download_kernel_src_apt
94         else
95                 download_kernel_src_yum
96         fi
97         cd linux-*
98 }
99
100 function apply_wc_patch {
101         echo "Using patch for kernel version 4.10"
102         local wc_patch="${BASE_PATH}/patches/linux-4.10-vfio-wc.patch"
103
104         if ! patch --ignore-whitespace -p1 < "${wc_patch}"; then
105                 err "Cannot apply patch: ${wc_patch}!"
106                 exit 1
107         fi
108 }
109
110 function compile_vfio_driver {
111         bold "\n[2] Patch and build the vfio driver"
112         # Adjust VFIO-PCI driver
113
114         bold "Apply patch for the write combining to the vfio-pci"
115         apply_wc_patch
116         green Done
117
118         cd drivers/vfio
119         # Configure Makefile - build VFIO with support for NOIOMMU mode
120         bold "\nConfigure Makefile for standalone vfio build and noiommu mode support"
121         echo "ccflags-y := -DCONFIG_VFIO_NOIOMMU=1" >> Makefile
122         echo 'all:' >> Makefile
123         echo '  make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules' >> Makefile
124         green Done
125
126         bold "\nBuild the driver"
127         if ! make; then
128                 err "Compilation error."
129                 exit 1
130         fi
131         green Done
132 }
133
134 function get_module_location {
135         for p in ${P1} ${P2}; do
136                 if find "${p}" -name "vfio.*" >/dev/null 2>/dev/null; then
137                         MOD_PATH="${p}"
138                         break
139                 fi
140         done
141
142         if [ -z "${MOD_PATH}" ]; then
143                 err "Cannot find kernel modules location..."
144                 exit
145         fi
146 }
147
148 function get_module_compression {
149         if ls "${MOD_PATH}/vfio.ko.xz" >/dev/null 2>/dev/null; then
150                 XZ=".xz"
151         else
152                 XZ=""
153         fi
154 }
155
156 function replace_module {
157         local installed=0
158
159         bold "\n[3] Install module"
160         get_module_location
161         get_module_compression
162
163         for name in "pci/vfio-pci.ko" "pci/vfio-pci-core.ko" "vfio.ko"; do
164                 if test -e "${MOD_PATH}/${name}${XZ}"; then
165                         if [ -n "${XZ}" ]; then
166                                 xz "${name}" -c > "${name}${XZ}"
167                         fi
168                         mv "${MOD_PATH}/${name}${XZ}" "${MOD_PATH}/${name}${XZ}_no_wc"
169                         cp "${name}${XZ}" "${MOD_PATH}/${name}${XZ}"
170                         bold "Installing: ${MOD_PATH}/${name}${XZ}"
171                         installed=1
172                 fi
173         done
174         if [ "${installed}" -eq 1 ]; then
175                 green "Module installed at: ${MOD_PATH}"
176         else
177                 err "Failure during vfio-pci module installation. Prehaps it's not provided as a kernel module!"
178                 exit 1
179         fi
180 }
181
182 ###############################################
183 # Main script code
184 ###############################################
185
186 if [ "$(id -u)" -ne 0 ]; then
187         err 'Please execute script as a root'
188         exit 1
189 fi
190
191 cd $(dirname ${0})
192 BASE_PATH=$(pwd)
193
194 KERNEL_VERSION=$(get_kernel_version)
195
196 if [ "${KERNEL_VERSION}" -lt 4100000 ]; then
197         err "Kernel version: $(uname -r) is not supported by the script. Please upgrade kernel to at least v4.10."
198         exit 1
199 fi
200
201 download_kernel_src
202 compile_vfio_driver
203 replace_module