在 s390 上測試 BPF

1. 引言

IBM Z 是大型機,是 1964 年 IBM System/360 的後代。它們在 Linux 核心中以“s390”的名稱得到支援。本文件描述瞭如何在 s390 QEMU 客戶機中測試 BPF。

2. 一次性設定

構建和執行測試套件需要以下內容:

  • s390 GCC

  • s390 開發標頭檔案和庫

  • 支援 BPF 的 Clang

  • 支援 s390 的 QEMU

  • 帶有 s390 rootfs 的磁碟映象

Debian 開箱即用支援安裝 s390 的編譯器和庫。其他發行版的使用者可以使用 debootstrap 來設定 Debian chroot

sudo debootstrap \
  --variant=minbase \
  --include=sudo \
  testing \
  ./s390-toolchain
sudo mount --rbind /dev ./s390-toolchain/dev
sudo mount --rbind /proc ./s390-toolchain/proc
sudo mount --rbind /sys ./s390-toolchain/sys
sudo chroot ./s390-toolchain

在 Debian 上,構建先決條件可以按如下方式安裝:

sudo dpkg --add-architecture s390x
sudo apt-get update
sudo apt-get install \
  bc \
  bison \
  cmake \
  debootstrap \
  dwarves \
  flex \
  g++ \
  gcc \
  g++-s390x-linux-gnu \
  gcc-s390x-linux-gnu \
  gdb-multiarch \
  git \
  make \
  python3 \
  qemu-system-misc \
  qemu-utils \
  rsync \
  libcap-dev:s390x \
  libelf-dev:s390x \
  libncurses-dev

針對 BPF 的最新 Clang 可以按如下方式安裝:

git clone https://github.com/llvm/llvm-project.git
ln -s ../../clang llvm-project/llvm/tools/
mkdir llvm-project-build
cd llvm-project-build
cmake \
  -DLLVM_TARGETS_TO_BUILD=BPF \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_INSTALL_PREFIX=/opt/clang-bpf \
  ../llvm-project/llvm
make
sudo make install
export PATH=/opt/clang-bpf/bin:$PATH

可以使用迴環掛載和 debootstrap 準備磁碟映象

qemu-img create -f raw ./s390.img 1G
sudo losetup -f ./s390.img
sudo mkfs.ext4 /dev/loopX
mkdir ./s390.rootfs
sudo mount /dev/loopX ./s390.rootfs
sudo debootstrap \
  --foreign \
  --arch=s390x \
  --variant=minbase \
  --include=" \
    iproute2, \
    iputils-ping, \
    isc-dhcp-client, \
    kmod, \
    libcap2, \
    libelf1, \
    netcat, \
    procps" \
  testing \
  ./s390.rootfs
sudo umount ./s390.rootfs
sudo losetup -d /dev/loopX

3. 編譯

除了執行 BPF 測試套件所需的常見 Kconfig 選項外,選擇以下選項也很有幫助:

CONFIG_NET_9P=y
CONFIG_9P_FS=y
CONFIG_NET_9P_VIRTIO=y
CONFIG_VIRTIO_PCI=y

因為這將提供一種非常簡便的方式來與 s390 虛擬機器共享檔案。

編譯核心、模組和測試套件,以及準備 gdb 指令碼以簡化除錯,可以使用以下命令完成:

make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- menuconfig
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- bzImage modules scripts_gdb
make ARCH=s390 CROSS_COMPILE=s390x-linux-gnu- \
  -C tools/testing/selftests \
  TARGETS=bpf \
  INSTALL_PATH=$PWD/tools/testing/selftests/kselftest_install \
  install

4. 執行測試套件

虛擬機器可以按如下方式啟動:

qemu-system-s390x \
  -cpu max,zpci=on \
  -smp 2 \
  -m 4G \
  -kernel linux/arch/s390/boot/compressed/vmlinux \
  -drive file=./s390.img,if=virtio,format=raw \
  -nographic \
  -append 'root=/dev/vda rw console=ttyS1' \
  -virtfs local,path=./linux,security_model=none,mount_tag=linux \
  -object rng-random,filename=/dev/urandom,id=rng0 \
  -device virtio-rng-ccw,rng=rng0 \
  -netdev user,id=net0 \
  -device virtio-net-ccw,netdev=net0

在真實的 IBM Z 上使用時,-enable-kvm 可以新增以獲得更好的效能。首次啟動虛擬機器時,必須使用以下命令完成磁碟映象的設定:

/debootstrap/debootstrap --second-stage

主機上構建的程式碼目錄以及 /proc/sys 需要按如下方式掛載:

mkdir -p /linux
mount -t 9p linux /linux
mount -t proc proc /proc
mount -t sysfs sys /sys

之後,測試套件可以使用以下命令執行:

cd /linux/tools/testing/selftests/kselftest_install
./run_kselftest.sh

與往常一樣,測試也可以單獨執行。

cd /linux/tools/testing/selftests/bpf
./test_verifier

5. 除錯

可以使用 QEMU GDB stub 除錯 s390 核心,透過向 QEMU 傳遞 -s 來啟用。

最好關閉 KASLR,以便 gdb 知道在記憶體中找到核心映象的位置,方法是使用以下命令構建核心:

RANDOMIZE_BASE=n

然後可以使用以下命令附加 GDB:

gdb-multiarch -ex 'target remote localhost:1234' ./vmlinux

6. 網路

如果需要在虛擬機器中使用網路(例如安裝額外的軟體包),可以透過以下方式配置:

dhclient eth0