1#!/bin/sh -e 2# 3# Update Linux kernel headers QEMU requires from a specified kernel tree. 4# 5# Copyright (C) 2011 Siemens AG 6# 7# Authors: 8# Jan Kiszka <jan.kiszka@siemens.com> 9# 10# This work is licensed under the terms of the GNU GPL version 2. 11# See the COPYING file in the top-level directory. 12# 13# The script will copy the headers into two target folders: 14# 15# - linux-headers/ for files that are required for compiling for a 16# Linux host. Generally we have these so we can use kernel structs 17# and defines that are more recent than the headers that might be 18# installed on the host system. Usually this script can do simple 19# file copies for these headers. 20# 21# - include/standard-headers/ for files that are used for guest 22# device emulation and are required on all hosts. For instance, we 23# get our definitions of the virtio structures from the Linux 24# kernel headers, but we need those definitions regardless of which 25# host OS we are building for. This script has to be careful to 26# sanitize the headers to remove any use of Linux-specifics such as 27# types like "__u64". This work is done in the cp_portable function. 28 29tmpdir=$(mktemp -d) 30hdrdir="$tmpdir/headers" 31blddir="$tmpdir/build" 32linux="$1" 33output="$2" 34 35if [ -z "$linux" ] || ! [ -d "$linux" ]; then 36 cat << EOF 37usage: update-kernel-headers.sh LINUX_PATH [OUTPUT_PATH] 38 39LINUX_PATH Linux kernel directory to obtain the headers from 40OUTPUT_PATH output directory, usually the qemu source tree (default: $PWD) 41EOF 42 exit 1 43fi 44 45if [ -z "$output" ]; then 46 output="$PWD" 47fi 48 49cp_portable() { 50 f=$1 51 to=$2 52 if 53 grep '#include' "$f" | grep -v -e 'linux/virtio' \ 54 -e 'linux/types' \ 55 -e 'linux/ioctl' \ 56 -e 'stdint' \ 57 -e 'linux/if_ether' \ 58 -e 'input-event-codes' \ 59 -e 'sys/' \ 60 -e 'drm.h' \ 61 -e 'limits' \ 62 -e 'linux/const' \ 63 -e 'linux/kernel' \ 64 -e 'linux/sysinfo' \ 65 -e 'asm/setup_data.h' \ 66 -e 'asm/kvm_para.h' \ 67 > /dev/null 68 then 69 echo "Unexpected #include in input file $f". 70 exit 2 71 fi 72 73 header=$(basename "$f"); 74 75 if test -z "$arch"; then 76 # Let users of include/standard-headers/linux/ headers pick the 77 # asm-* header that they care about 78 arch_cmd='/<asm\/\([^>]*\)>/d' 79 else 80 arch_cmd='s/<asm\/\([^>]*\)>/"standard-headers\/asm-'$arch'\/\1"/' 81 fi 82 83 sed -e 's/__aligned_u64/__u64 __attribute__((aligned(8)))/g' \ 84 -e 's/__u\([0-9][0-9]*\)/uint\1_t/g' \ 85 -e 's/u\([0-9][0-9]*\)/uint\1_t/g' \ 86 -e 's/__s\([0-9][0-9]*\)/int\1_t/g' \ 87 -e 's/__le\([0-9][0-9]*\)/uint\1_t/g' \ 88 -e 's/__be\([0-9][0-9]*\)/uint\1_t/g' \ 89 -e 's/"\(input-event-codes\.h\)"/"standard-headers\/linux\/\1"/' \ 90 -e 's/<linux\/\([^>]*\)>/"standard-headers\/linux\/\1"/' \ 91 -e "$arch_cmd" \ 92 -e 's/__bitwise//' \ 93 -e 's/__attribute__((packed))/QEMU_PACKED/' \ 94 -e 's/__inline__/inline/' \ 95 -e 's/__BITS_PER_LONG/HOST_LONG_BITS/' \ 96 -e '/\"drm.h\"/d' \ 97 -e '/sys\/ioctl.h/d' \ 98 -e '/linux\/ioctl.h/d' \ 99 -e 's/SW_MAX/SW_MAX_/' \ 100 -e 's/atomic_t/int/' \ 101 -e 's/__kernel_long_t/long/' \ 102 -e 's/__kernel_ulong_t/unsigned long/' \ 103 -e 's/struct ethhdr/struct eth_header/' \ 104 -e '/\#define _LINUX_ETHTOOL_H/a \\n\#include "net/eth.h"' \ 105 "$f" > "$to/$header"; 106} 107 108# This will pick up non-directories too (eg "Kconfig") but we will 109# ignore them in the next loop. 110ARCHLIST=$(cd "$linux/arch" && echo *) 111 112for arch in $ARCHLIST; do 113 # Discard anything which isn't a KVM-supporting architecture 114 if ! [ -e "$linux/arch/$arch/include/asm/kvm.h" ] && 115 ! [ -e "$linux/arch/$arch/include/uapi/asm/kvm.h" ] ; then 116 continue 117 fi 118 119 if [ "$arch" = x86 ]; then 120 arch_var=SRCARCH 121 else 122 arch_var=ARCH 123 fi 124 125 rm -rf "$hdrdir" 126 make -C "$linux" O="$blddir" INSTALL_HDR_PATH="$hdrdir" $arch_var=$arch headers_install 127 128 rm -rf "$output/linux-headers/asm-$arch" 129 mkdir -p "$output/linux-headers/asm-$arch" 130 for header in kvm.h unistd.h bitsperlong.h mman.h; do 131 if test -f "$hdrdir/include/asm/$header"; then 132 cp "$hdrdir/include/asm/$header" "$output/linux-headers/asm-$arch" 133 elif test -f "$hdrdir/include/asm-generic/$header"; then 134 # not installed as <asm/$header>, but used as such in kernel sources 135 cat <<EOF >$output/linux-headers/asm-$arch/$header 136#include <asm-generic/$header> 137EOF 138 fi 139 done 140 141 if [ $arch = mips ]; then 142 cp "$hdrdir/include/asm/sgidefs.h" "$output/linux-headers/asm-mips/" 143 cp "$hdrdir/include/asm/unistd_o32.h" "$output/linux-headers/asm-mips/" 144 cp "$hdrdir/include/asm/unistd_n32.h" "$output/linux-headers/asm-mips/" 145 cp "$hdrdir/include/asm/unistd_n64.h" "$output/linux-headers/asm-mips/" 146 fi 147 if [ $arch = powerpc ]; then 148 cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-powerpc/" 149 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-powerpc/" 150 fi 151 152 rm -rf "$output/include/standard-headers/asm-$arch" 153 mkdir -p "$output/include/standard-headers/asm-$arch" 154 if [ $arch = s390 ]; then 155 cp_portable "$hdrdir/include/asm/virtio-ccw.h" "$output/include/standard-headers/asm-s390/" 156 cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-s390/" 157 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-s390/" 158 fi 159 if [ $arch = arm ]; then 160 cp "$hdrdir/include/asm/unistd-eabi.h" "$output/linux-headers/asm-arm/" 161 cp "$hdrdir/include/asm/unistd-oabi.h" "$output/linux-headers/asm-arm/" 162 cp "$hdrdir/include/asm/unistd-common.h" "$output/linux-headers/asm-arm/" 163 fi 164 if [ $arch = arm64 ]; then 165 cp "$hdrdir/include/asm/sve_context.h" "$output/linux-headers/asm-arm64/" 166 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-arm64/" 167 fi 168 if [ $arch = x86 ]; then 169 cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-x86/" 170 cp "$hdrdir/include/asm/unistd_x32.h" "$output/linux-headers/asm-x86/" 171 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-x86/" 172 173 cp_portable "$hdrdir/include/asm/kvm_para.h" "$output/include/standard-headers/asm-$arch" 174 cat <<EOF >$output/linux-headers/asm-$arch/kvm_para.h 175#include "standard-headers/asm-$arch/kvm_para.h" 176EOF 177 178 # Remove everything except the macros from bootparam.h avoiding the 179 # unnecessary import of several video/ist/etc headers 180 sed -e '/__ASSEMBLY__/,/__ASSEMBLY__/d' \ 181 "$hdrdir/include/asm/bootparam.h" > "$hdrdir/bootparam.h" 182 cp_portable "$hdrdir/bootparam.h" \ 183 "$output/include/standard-headers/asm-$arch" 184 cp_portable "$hdrdir/include/asm/setup_data.h" \ 185 "$output/include/standard-headers/asm-x86" 186 fi 187 if [ $arch = riscv ]; then 188 cp "$hdrdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" 189 cp "$hdrdir/include/asm/unistd_32.h" "$output/linux-headers/asm-riscv/" 190 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-riscv/" 191 fi 192 if [ $arch = loongarch ]; then 193 cp "$hdrdir/include/asm/kvm_para.h" "$output/linux-headers/asm-loongarch/" 194 cp "$hdrdir/include/asm/unistd_64.h" "$output/linux-headers/asm-loongarch/" 195 fi 196done 197arch= 198 199rm -rf "$output/linux-headers/linux" 200mkdir -p "$output/linux-headers/linux" 201for header in const.h stddef.h kvm.h vfio.h vfio_ccw.h vfio_zdev.h vhost.h \ 202 psci.h psp-sev.h userfaultfd.h memfd.h mman.h nvme_ioctl.h \ 203 vduse.h iommufd.h bits.h; do 204 cp "$hdrdir/include/linux/$header" "$output/linux-headers/linux" 205done 206 207rm -rf "$output/linux-headers/asm-generic" 208mkdir -p "$output/linux-headers/asm-generic" 209for header in unistd.h bitsperlong.h mman-common.h mman.h hugetlb_encode.h; do 210 cp "$hdrdir/include/asm-generic/$header" "$output/linux-headers/asm-generic" 211done 212 213if [ -L "$linux/source" ]; then 214 cp "$linux/source/COPYING" "$output/linux-headers" 215else 216 cp "$linux/COPYING" "$output/linux-headers" 217fi 218 219# Recent kernel sources split the copyright/license info into multiple 220# files, which we need to copy. This set of licenses is the set that 221# are referred to by SPDX lines in the headers we currently copy. 222# We don't copy the Documentation/process/license-rules.rst which 223# is also referred to by COPYING, since it's explanatory rather than license. 224if [ -d "$linux/LICENSES" ]; then 225 mkdir -p "$output/linux-headers/LICENSES/preferred" \ 226 "$output/linux-headers/LICENSES/exceptions" 227 for l in preferred/GPL-2.0 preferred/BSD-2-Clause preferred/BSD-3-Clause \ 228 exceptions/Linux-syscall-note; do 229 cp "$linux/LICENSES/$l" "$output/linux-headers/LICENSES/$l" 230 done 231fi 232 233cat <<EOF >$output/linux-headers/linux/kvm_para.h 234#include "standard-headers/linux/kvm_para.h" 235#include <asm/kvm_para.h> 236EOF 237cat <<EOF >$output/linux-headers/linux/virtio_config.h 238#include "standard-headers/linux/virtio_config.h" 239EOF 240cat <<EOF >$output/linux-headers/linux/virtio_ring.h 241#include "standard-headers/linux/virtio_ring.h" 242EOF 243cat <<EOF >$output/linux-headers/linux/vhost_types.h 244#include "standard-headers/linux/vhost_types.h" 245EOF 246 247rm -rf "$output/include/standard-headers/linux" 248mkdir -p "$output/include/standard-headers/linux" 249for i in "$hdrdir"/include/linux/*virtio*.h \ 250 "$hdrdir/include/linux/qemu_fw_cfg.h" \ 251 "$hdrdir/include/linux/fuse.h" \ 252 "$hdrdir/include/linux/input.h" \ 253 "$hdrdir/include/linux/input-event-codes.h" \ 254 "$hdrdir/include/linux/udmabuf.h" \ 255 "$hdrdir/include/linux/pci_regs.h" \ 256 "$hdrdir/include/linux/ethtool.h" \ 257 "$hdrdir/include/linux/const.h" \ 258 "$hdrdir/include/linux/kernel.h" \ 259 "$hdrdir/include/linux/kvm_para.h" \ 260 "$hdrdir/include/linux/vhost_types.h" \ 261 "$hdrdir/include/linux/sysinfo.h"; do 262 cp_portable "$i" "$output/include/standard-headers/linux" 263done 264mkdir -p "$output/include/standard-headers/misc" 265cp_portable "$hdrdir/include/misc/pvpanic.h" \ 266 "$output/include/standard-headers/misc" 267mkdir -p "$output/include/standard-headers/drm" 268cp_portable "$hdrdir/include/drm/drm_fourcc.h" \ 269 "$output/include/standard-headers/drm" 270 271cat <<EOF >$output/include/standard-headers/linux/types.h 272/* For QEMU all types are already defined via osdep.h, so this 273 * header does not need to do anything. 274 */ 275EOF 276cat <<EOF >$output/include/standard-headers/linux/if_ether.h 277#define ETH_ALEN 6 278EOF 279 280rm -rf "$tmpdir" 281