From d8a94cd0c8992ca7f1c48ee94c4c1f432bfdddc6 Mon Sep 17 00:00:00 2001 From: Kernel Patches Daemon Date: Mon, 25 Sep 2023 16:43:50 -0700 Subject: [PATCH] adding ci files --- .../veristat_baseline_compare/action.yml | 49 +++ .github/scripts/bpf-objects-rootfs.sh | 12 + .github/scripts/compare-veristat-results.sh | 18 + .github/scripts/get-commit-metadata.sh | 23 ++ .github/scripts/matrix.py | 141 +++++++ .github/scripts/prepare-incremental-builds.sh | 63 ++++ .github/scripts/tar-artifact.sh | 46 +++ .github/scripts/veristat-compare.py | 202 ++++++++++ .github/workflows/lint.yml | 22 ++ .github/workflows/test.yml | 253 +++++++++++++ README | 18 - ci/diffs/.keep | 0 ...x-broken-BuildID-for-arm64-and-riscv.patch | 30 ++ ...btf_put-to-register_btf_id_dtor_kfun.patch | 41 ++ ...r-expectations-from-bpf_clone_redire.patch | 58 +++ ...issing-nospec.h-to-avoid-build-error.patch | 45 +++ ...-pointer-dereference-when-pin-PROG-M.patch | 45 +++ ...type_data_check_overflow-needs-to-co.patch | 115 ++++++ ...les-bpf-drop-unnecessary-fallthrough.patch | 32 ++ ...001-selftests-bpf-Add-config.aarch64.patch | 207 ++++++++++ ...dd-json-summary-option-to-test_progs.patch | 357 ++++++++++++++++++ ...just-expected-error-message-for-test.patch | 43 +++ ...x-compilation-errors-Assign-a-value-.patch | 50 +++ ...ests-bpf-Fix-decap_sanity_ns-cleanup.patch | 36 ++ ...sts-bpf-Initial-DENYLIST-for-aarch64.patch | 118 ++++++ ...ftests-bpf-Panic-on-hard-soft-lockup.patch | 57 +++ ...iptables-iptables-legacy-in-the-bpf_.patch | 77 ++++ ...lect-CONFIG_FUNCTION_ERROR_INJECTION.patch | 45 +++ ...x-up-Andrii-s-BPF-token-v5-patch-set.patch | 32 ++ ...nitialize-ret-valiable-to-fix-smatch.patch | 68 ++++ ...ccount-peer-device-for-NETDEV_XDP_AC.patch | 83 ++++ ...ally-export-__vdso_sgx_enter_enclave.patch | 44 +++ ...Set-CONFIG_BOOTPARAM_HUNG_TASK_PANIC.patch | 39 ++ ...date-bpf_clone_redirect-expected-ret.patch | 82 ++++ ...pi-pull-in-stddef.h-to-fix-BPF-selft.patch | 104 +++++ ci/vmtest/configs/DENYLIST | 7 + ci/vmtest/configs/DENYLIST.aarch64 | 4 + ci/vmtest/configs/DENYLIST.s390x | 5 + ci/vmtest/configs/DENYLIST.x86_64 | 1 + ci/vmtest/configs/run_veristat.kernel.cfg | 3 + ci/vmtest/configs/run_veristat.meta.cfg | 3 + ci/vmtest/helpers.sh | 38 ++ ci/vmtest/run_selftests.sh | 189 ++++++++++ 43 files changed, 2887 insertions(+), 18 deletions(-) create mode 100644 .github/actions/veristat_baseline_compare/action.yml create mode 100755 .github/scripts/bpf-objects-rootfs.sh create mode 100755 .github/scripts/compare-veristat-results.sh create mode 100644 .github/scripts/get-commit-metadata.sh create mode 100644 .github/scripts/matrix.py create mode 100644 .github/scripts/prepare-incremental-builds.sh create mode 100644 .github/scripts/tar-artifact.sh create mode 100644 .github/scripts/veristat-compare.py create mode 100644 .github/workflows/lint.yml create mode 100644 .github/workflows/test.yml create mode 100644 ci/diffs/.keep create mode 100644 ci/diffs/0001-Revert-arch-fix-broken-BuildID-for-arm64-and-riscv.patch create mode 100644 ci/diffs/0001-bpf-Add-missing-btf_put-to-register_btf_id_dtor_kfun.patch create mode 100644 ci/diffs/0001-bpf-Clarify-error-expectations-from-bpf_clone_redire.patch create mode 100644 ci/diffs/0001-bpf-Include-missing-nospec.h-to-avoid-build-error.patch create mode 100644 ci/diffs/0001-bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch create mode 100644 ci/diffs/0001-libbpf-btf_dump_type_data_check_overflow-needs-to-co.patch create mode 100644 ci/diffs/0001-samples-bpf-drop-unnecessary-fallthrough.patch create mode 100644 ci/diffs/0001-selftests-bpf-Add-config.aarch64.patch create mode 100644 ci/diffs/0001-selftests-bpf-Add-json-summary-option-to-test_progs.patch create mode 100644 ci/diffs/0001-selftests-bpf-Adjust-expected-error-message-for-test.patch create mode 100644 ci/diffs/0001-selftests-bpf-Fix-compilation-errors-Assign-a-value-.patch create mode 100644 ci/diffs/0001-selftests-bpf-Fix-decap_sanity_ns-cleanup.patch create mode 100644 ci/diffs/0001-selftests-bpf-Initial-DENYLIST-for-aarch64.patch create mode 100644 ci/diffs/0001-selftests-bpf-Panic-on-hard-soft-lockup.patch create mode 100644 ci/diffs/0001-selftests-bpf-S-iptables-iptables-legacy-in-the-bpf_.patch create mode 100644 ci/diffs/0001-selftests-bpf-Select-CONFIG_FUNCTION_ERROR_INJECTION.patch create mode 100644 ci/diffs/0001-selftests-bpf-fix-up-Andrii-s-BPF-token-v5-patch-set.patch create mode 100644 ci/diffs/0001-tracing-fprobe-Initialize-ret-valiable-to-fix-smatch.patch create mode 100644 ci/diffs/0001-veth-take-into-account-peer-device-for-NETDEV_XDP_AC.patch create mode 100644 ci/diffs/0001-x86-vdso-Conditionally-export-__vdso_sgx_enter_enclave.patch create mode 100644 ci/diffs/0002-selftests-bpf-Set-CONFIG_BOOTPARAM_HUNG_TASK_PANIC.patch create mode 100644 ci/diffs/0002-selftests-bpf-Update-bpf_clone_redirect-expected-ret.patch create mode 100644 ci/diffs/0002-tools-headers-uapi-pull-in-stddef.h-to-fix-BPF-selft.patch create mode 100644 ci/vmtest/configs/DENYLIST create mode 100644 ci/vmtest/configs/DENYLIST.aarch64 create mode 100644 ci/vmtest/configs/DENYLIST.s390x create mode 100644 ci/vmtest/configs/DENYLIST.x86_64 create mode 100644 ci/vmtest/configs/run_veristat.kernel.cfg create mode 100644 ci/vmtest/configs/run_veristat.meta.cfg create mode 100755 ci/vmtest/helpers.sh create mode 100755 ci/vmtest/run_selftests.sh diff --git a/.github/actions/veristat_baseline_compare/action.yml b/.github/actions/veristat_baseline_compare/action.yml new file mode 100644 index 0000000000000..7ea487af61b8d --- /dev/null +++ b/.github/actions/veristat_baseline_compare/action.yml @@ -0,0 +1,49 @@ +name: 'run-veristat' +description: 'Run veristat benchmark' +inputs: + veristat_output: + description: 'Veristat output filepath' + required: true + baseline_name: + description: 'Veristat baseline cache name' + required: true +runs: + using: "composite" + steps: + - uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.baseline_name }} + if-no-files-found: error + path: ${{ github.workspace }}/${{ inputs.veristat_output }} + + # For pull request: + # - get baseline log from cache + # - compare it to current run + - if: ${{ github.event_name == 'pull_request' }} + uses: actions/cache/restore@v3 + with: + key: ${{ inputs.baseline_name }} + restore-keys: | + ${{ inputs.baseline_name }}- + path: '${{ github.workspace }}/${{ inputs.baseline_name }}' + + - if: ${{ github.event_name == 'pull_request' }} + name: Show veristat comparison + shell: bash + run: ./.github/scripts/compare-veristat-results.sh + env: + BASELINE_PATH: ${{ github.workspace }}/${{ inputs.baseline_name }} + VERISTAT_OUTPUT: ${{ inputs.veristat_output }} + + # For push: just put baseline log to cache + - if: ${{ github.event_name == 'push' }} + shell: bash + run: | + mv "${{ github.workspace }}/${{ inputs.veristat_output }}" \ + "${{ github.workspace }}/${{ inputs.baseline_name }}" + + - if: ${{ github.event_name == 'push' }} + uses: actions/cache/save@v3 + with: + key: ${{ inputs.baseline_name }}-${{ github.run_id }} + path: '${{ github.workspace }}/${{ inputs.baseline_name }}' diff --git a/.github/scripts/bpf-objects-rootfs.sh b/.github/scripts/bpf-objects-rootfs.sh new file mode 100755 index 0000000000000..223e3ee350777 --- /dev/null +++ b/.github/scripts/bpf-objects-rootfs.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +eval "$(guestfish --listen)" + +guestfish --verbose --remote \ + add /tmp/root.img label:img : \ + launch : \ + mount /dev/disk/guestfs/img / : \ + copy-in /tmp/bpf_objects / : \ + chmod 0755 /bpf_objects + +guestfish --remote exit diff --git a/.github/scripts/compare-veristat-results.sh b/.github/scripts/compare-veristat-results.sh new file mode 100755 index 0000000000000..f15e759f53b5c --- /dev/null +++ b/.github/scripts/compare-veristat-results.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [[ ! -f "${BASELINE_PATH}" ]]; then + echo "# No ${BASELINE_PATH} available" >> "${GITHUB_STEP_SUMMARY}" + + echo "No ${BASELINE_PATH} available" + echo "Printing veristat results" + cat "${VERISTAT_OUTPUT}" + + exit +fi + +selftests/bpf/veristat \ + --output-format csv \ + --emit file,prog,verdict,states \ + --compare "${BASELINE_PATH}" "${VERISTAT_OUTPUT}" > compare.csv + +python3 ./.github/scripts/veristat-compare.py compare.csv diff --git a/.github/scripts/get-commit-metadata.sh b/.github/scripts/get-commit-metadata.sh new file mode 100644 index 0000000000000..f178786e4e58a --- /dev/null +++ b/.github/scripts/get-commit-metadata.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +branch="${GITHUB_BASE_REF}" + +if [ "${GITHUB_EVENT_NAME}" = 'push' ]; then + branch="${GITHUB_REF_NAME}" +fi + +echo "branch=${branch}" >> "${GITHUB_OUTPUT}" + +upstream="${branch//_base/}" +commit="$( + git rev-parse "origin/${upstream}" &> /dev/null \ + || ( + git fetch --quiet --prune --no-tags --depth=1 --no-recurse-submodules origin "+refs/heads/${upstream}:refs/remotes/origin/${upstream}" && \ + git rev-parse "origin/${upstream}" + ) +)" +timestamp_utc="$(TZ=utc git show --format='%cd' --no-patch --date=iso-strict-local "${commit}")" + +echo "timestamp=${timestamp_utc}" >> "${GITHUB_OUTPUT}" +echo "commit=${commit}" >> "${GITHUB_OUTPUT}" +echo "Most recent upstream commit is ${commit}" diff --git a/.github/scripts/matrix.py b/.github/scripts/matrix.py new file mode 100644 index 0000000000000..4e8ef4c738a3c --- /dev/null +++ b/.github/scripts/matrix.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 + +from json import dumps +from enum import Enum +import os + + +class Arch(Enum): + """ + CPU architecture supported by CI. + """ + + AARCH64 = "aarch64" + S390X = "s390x" + X86_64 = "x86_64" + + +def set_output(name, value): + """Write an output variable to the GitHub output file.""" + with open(os.getenv("GITHUB_OUTPUT"), "a", encoding="utf-8") as file: + file.write(f"{name}={value}\n") + + +def generate_test_config(test): + """Create the configuration for the provided test.""" + experimental = test.endswith("_parallel") + config = { + "test": test, + "continue_on_error": experimental, + # While in experimental mode, parallel jobs may get stuck + # anywhere, including in user space where the kernel won't detect + # a problem and panic. We add a second layer of (smaller) timeouts + # here such that if we get stuck in a parallel run, we hit this + # timeout and fail without affecting the overall job success (as + # would be the case if we hit the job-wide timeout). For + # non-experimental jobs, 360 is the default which will be + # superseded by the overall workflow timeout (but we need to + # specify something). + "timeout_minutes": 30 if experimental else 360, + } + return config + + +def get_tests(config): + tests = [ + "test_progs", + "test_progs_parallel", + "test_progs_no_alu32", + "test_progs_no_alu32_parallel", + "test_maps", + "test_verifier", + ] + if config.get("parallel_tests", True): + return tests + return [test for test in tests if not test.endswith("parallel")] + + +matrix = [ + { + "kernel": "LATEST", + "runs_on": [], + "arch": Arch.X86_64.value, + "toolchain": "gcc", + "llvm-version": "16", + }, + { + "kernel": "LATEST", + "runs_on": [], + "arch": Arch.X86_64.value, + "toolchain": "llvm", + "llvm-version": "16", + }, + { + "kernel": "LATEST", + "runs_on": [], + "arch": Arch.AARCH64.value, + "toolchain": "gcc", + "llvm-version": "16", + }, + # { + # "kernel": "LATEST", + # "runs_on": [], + # "arch": Arch.AARCH64.value, + # "toolchain": "llvm", + # "llvm-version": "16", + # }, + { + "kernel": "LATEST", + "runs_on": [], + "arch": Arch.S390X.value, + "toolchain": "gcc", + "llvm-version": "16", + "parallel_tests": False, + }, +] +self_hosted_repos = [ + "kernel-patches/bpf", + "kernel-patches/vmtest", +] + +for idx in range(len(matrix) - 1, -1, -1): + if matrix[idx]["toolchain"] == "gcc": + matrix[idx]["toolchain_full"] = "gcc" + else: + matrix[idx]["toolchain_full"] = "llvm-" + matrix[idx]["llvm-version"] + +# Only a few repository within "kernel-patches" use self-hosted runners. +if ( + os.environ["GITHUB_REPOSITORY_OWNER"] != "kernel-patches" + or os.environ["GITHUB_REPOSITORY"] not in self_hosted_repos +): + # Outside of those repositories, we only run on x86_64 GH hosted runners (ubuntu-latest) + for idx in range(len(matrix) - 1, -1, -1): + if matrix[idx]["arch"] != Arch.X86_64.value: + del matrix[idx] + else: + matrix[idx]["runs_on"] = ["ubuntu-latest"] +else: + # Otherwise, run on (self-hosted, arch) runners + for idx in range(len(matrix) - 1, -1, -1): + matrix[idx]["runs_on"].extend(["self-hosted", matrix[idx]["arch"]]) + +build_matrix = {"include": matrix} +set_output("build_matrix", dumps(build_matrix)) + +test_matrix = { + "include": [ + {**config, **generate_test_config(test)} + for config in matrix + for test in get_tests(config) + ] +} +set_output("test_matrix", dumps(test_matrix)) + +veristat_runs_on = next( + x["runs_on"] + for x in matrix + if x["arch"] == os.environ["veristat_arch"] + and x["toolchain"] == os.environ["veristat_toolchain"] +) +set_output("veristat_runs_on", veristat_runs_on) diff --git a/.github/scripts/prepare-incremental-builds.sh b/.github/scripts/prepare-incremental-builds.sh new file mode 100644 index 0000000000000..17f825480ff47 --- /dev/null +++ b/.github/scripts/prepare-incremental-builds.sh @@ -0,0 +1,63 @@ +#!/bin/bash + +set -eu + +commit_id="${1}" + +# $1 - the SHA-1 to fetch and check out +fetch_and_checkout() { + local build_base_sha + + build_base_sha="${1}" + # If cached artifacts became stale for one reason or another, we + # may not have the build base SHA available. Fetch it and retry. + git fetch origin "${build_base_sha}" && git checkout --quiet "${build_base_sha}" +} + +# $1 - value of KBUILD_OUTPUT +clear_cache_artifacts() { + local output_dir + + output_dir="${1}" + echo "Unable to find earlier upstream ref. Discarding KBUILD_OUTPUT contents..." + rm --recursive --force "${output_dir}" + mkdir "${output_dir}" + false +} + +# $1 - value of KBUILD_OUTPUT +# $2 - current time in ISO 8601 format +restore_source_code_times() { + local build_output + local current_time + local src_time + local obj_time + + build_output="${1}" + current_time="${2}" + src_time="$(date --iso-8601=ns --date="${current_time} - 2 minutes")" + obj_time="$(date --iso-8601=ns --date="${current_time} - 1 minute")" + + git ls-files | xargs --max-args=10000 touch -m --no-create --date="${src_time}" + find "${build_output}" -type f | xargs --max-args=10000 touch -m --no-create --date="${obj_time}" + git checkout --quiet - + echo "Adjusted src and obj time stamps relative to system time" +} + +mkdir --parents "${KBUILD_OUTPUT}" +current_time="$(date --iso-8601=ns)" + +if [ -f "${KBUILD_OUTPUT}/.build-base-sha" ]; then + build_base_sha="$(cat "${KBUILD_OUTPUT}/.build-base-sha")" + echo "Setting up base build state for ${build_base_sha}" + + ( + git checkout --quiet "${build_base_sha}" \ + || fetch_and_checkout "${build_base_sha}" \ + || clear_cache_artifacts "${KBUILD_OUTPUT}" + ) && restore_source_code_times "${KBUILD_OUTPUT}" "${current_time}" +else + echo "No previous build data found" +fi + +echo -n "${commit_id}" > "${KBUILD_OUTPUT}/.build-base-sha" diff --git a/.github/scripts/tar-artifact.sh b/.github/scripts/tar-artifact.sh new file mode 100644 index 0000000000000..cd88f9e84ba46 --- /dev/null +++ b/.github/scripts/tar-artifact.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +set -eux + +arch="${1}" +toolchain="${2}" + +# Remove intermediate object files that we have no use for. Ideally +# we'd just exclude them from tar below, but it does not provide +# options to express the precise constraints. +find selftests/ -name "*.o" -a ! -name "*.bpf.o" -print0 | \ + xargs --null --max-args=10000 rm + +# Strip debug information, which is excessively large (consuming +# bandwidth) while not actually being used (the kernel does not use +# DWARF to symbolize stacktraces). +strip --strip-debug "${KBUILD_OUTPUT}"/vmlinux + +additional_file_list=() +if [ "${GITHUB_REPOSITORY}" == "kernel-patches/vmtest" ]; then + # Package up a bunch of additional infrastructure to support running + # 'make kernelrelease' and bpf tool checks later on. + mapfile -t additional_file_list < <(find . -iname Makefile) + additional_file_list+=( + "scripts/" + "tools/testing/selftests/bpf/" + "tools/include/" + "tools/bpf/bpftool/" + ) +fi + +image_name=$(make -s image_name) + +# zstd is installed by default in the runner images. +tar -cf - \ + "${KBUILD_OUTPUT}/.config" \ + "${KBUILD_OUTPUT}/${image_name}" \ + "${KBUILD_OUTPUT}/include/config/auto.conf" \ + "${KBUILD_OUTPUT}/include/generated/autoconf.h" \ + "${KBUILD_OUTPUT}/vmlinux" \ + "${additional_file_list[@]}" \ + --exclude '*.cmd' \ + --exclude '*.d' \ + --exclude '*.h' \ + --exclude '*.output' \ + selftests/bpf/ | zstd -T0 -19 -o "vmlinux-${arch}-${toolchain}.tar.zst" diff --git a/.github/scripts/veristat-compare.py b/.github/scripts/veristat-compare.py new file mode 100644 index 0000000000000..588fa186597ad --- /dev/null +++ b/.github/scripts/veristat-compare.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 + +# This script reads a CSV file produced by the following invocation: +# +# veristat --emit file,prog,verdict,states \ +# --output-format csv \ +# --compare ... +# +# And produces a markdown summary for the file. +# The summary is printed to standard output and appended to a file +# pointed to by GITHUB_STEP_SUMMARY variable. +# +# Script exits with return code 1 if there are new failures in the +# veristat results. +# +# For testing purposes invoke as follows: +# +# GITHUB_STEP_SUMMARY=/dev/null python3 veristat-compare.py test.csv +# +# File format (columns): +# 0. file_name +# 1. prog_name +# 2. verdict_base +# 3. verdict_comp +# 4. verdict_diff +# 5. total_states_base +# 6. total_states_comp +# 7. total_states_diff +# +# Records sample: +# file-a,a,success,failure,MISMATCH,12,12,+0 (+0.00%) +# file-b,b,success,success,MATCH,67,67,+0 (+0.00%) +# +# For better readability suffixes '_OLD' and '_NEW' +# are used instead of '_base' and '_comp' for variable +# names etc. + +import io +import os +import sys +import csv +import logging +import argparse +from functools import reduce +from dataclasses import dataclass + +TRESHOLD_PCT = 0 + +HEADERS = ['file_name', 'prog_name', 'verdict_base', 'verdict_comp', + 'verdict_diff', 'total_states_base', 'total_states_comp', + 'total_states_diff'] + +FILE = 0 +PROG = 1 +VERDICT_OLD = 2 +VERDICT_NEW = 3 +STATES_OLD = 5 +STATES_NEW = 6 + +# Given a table row, compute relative increase in the number of +# processed states. +def compute_diff(v): + old = int(v[STATES_OLD]) if v[STATES_OLD] != 'N/A' else 0 + new = int(v[STATES_NEW]) if v[STATES_NEW] != 'N/A' else 0 + if old == 0: + return 1 + return (new - old) / old + +@dataclass +class VeristatInfo: + table: list + changes: bool + new_failures: bool + +# Read CSV table expecting the above described format. +# Return VeristatInfo instance. +def parse_table(csv_filename): + new_failures = False + changes = False + table = [] + + with open(csv_filename, newline='') as file: + reader = csv.reader(file) + headers = next(reader) + if headers != HEADERS: + raise Exception(f'Unexpected table header for {filename}: {headers}') + + for v in reader: + add = False + verdict = v[VERDICT_NEW] + diff = compute_diff(v) + + if v[VERDICT_OLD] != v[VERDICT_NEW]: + changes = True + add = True + verdict = f'{v[VERDICT_OLD]} -> {v[VERDICT_NEW]}' + if v[VERDICT_NEW] == 'failure': + new_failures = True + verdict += ' (!!)' + + if abs(diff * 100) > TRESHOLD_PCT: + changes = True + add = True + + if not add: + continue + + diff_txt = '{:+.1f} %'.format(diff * 100) + table.append([v[FILE], v[PROG], verdict, diff_txt]) + + return VeristatInfo(table=table, + changes=changes, + new_failures=new_failures) + +def format_table(headers, rows, html_mode): + def decorate(val, width): + s = str(val) + if html_mode: + s = s.replace(' -> ', ' → '); + s = s.replace(' (!!)', ' :bangbang: '); + return s.ljust(width) + + column_widths = list(reduce(lambda acc, row: map(max, map(len, row), acc), + rows, + map(len, headers))) + + with io.StringIO() as out: + def print_row(row): + out.write('| ') + out.write(' | '.join(map(decorate, row, column_widths))) + out.write(' |\n') + + print_row(headers) + + out.write('|') + out.write('|'.join(map(lambda w: '-' * (w + 2), column_widths))) + out.write('|\n') + + for row in rows: + print_row(row) + + return out.getvalue() + +def format_section_name(info): + if info.new_failures: + return 'There are new veristat failures' + if info.changes: + return 'There are changes in verification performance' + return 'No changes in verification performance' + +SUMMARY_HEADERS = ['File', 'Program', 'Verdict', 'States Diff (%)'] + +def format_html_summary(info): + section_name = format_section_name(info) + if not info.table: + return f'# {section_name}\n' + + table = format_table(SUMMARY_HEADERS, info.table, True) + return f''' +# {section_name} + +
+Click to expand + +{table} +
+'''.lstrip() + +def format_text_summary(info): + section_name = format_section_name(info) + table = format_table(SUMMARY_HEADERS, info.table, False) + if not info.table: + return f'# {section_name}\n' + + return f''' +# {section_name} + +{table} +'''.lstrip() + +def main(compare_csv_filename, summary_filename): + info = parse_table(compare_csv_filename) + sys.stdout.write(format_text_summary(info)) + with open(summary_filename, 'a') as f: + f.write(format_html_summary(info)) + + if info.new_failures: + return 1 + + return 0 + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description="""Print veristat comparison output as markdown step summary""" + ) + parser.add_argument('filename') + args = parser.parse_args() + summary_filename = os.getenv('GITHUB_STEP_SUMMARY') + if not summary_filename: + logging.error('GITHUB_STEP_SUMMARY environment variable is not set') + sys.exit(1) + sys.exit(main(args.filename, summary_filename)) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000000..8805283a42271 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,22 @@ +name: "lint" + +on: + pull_request: + push: + branches: + - master + +jobs: + shellcheck: + # This workflow gets injected into other Linux repositories, but we don't + # want it to run there. + if: ${{ github.repository == 'kernel-patches/vmtest' }} + name: ShellCheck + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@master + env: + SHELLCHECK_OPTS: --severity=warning --exclude=SC1091 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000000000..be9219fec8b18 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,253 @@ +name: bpf-ci + +on: + pull_request: + push: + branches: + - bpf_base + - bpf-next_base + +env: + veristat_arch: x86_64 + veristat_toolchain: gcc + +concurrency: + group: ci-test-${{ github.ref_name }} + cancel-in-progress: true + +jobs: + set-matrix: + # FIXME: set-matrix is lightweight, run it on any self-hosted machines for kernel-patches org + # so we do not wait for GH hosted runners when there potentially all are busy because of bpf-rc + # repo for instance. + # This could be somehow fixed long term by making this action/workflow re-usable and letting the called + # specify what to run on. + runs-on: ${{ github.repository_owner == 'kernel-patches' && 'x86_64' || 'ubuntu-latest' }} + outputs: + build-matrix: ${{ steps.set-matrix-impl.outputs.build_matrix }} + test-matrix: ${{ steps.set-matrix-impl.outputs.test_matrix }} + veristat-runs-on: ${{ steps.set-matrix-impl.outputs.veristat_runs_on }} + steps: + - uses: actions/checkout@v3 + - id: set-matrix-impl + run: | + python3 .github/scripts/matrix.py + build: + name: build for ${{ matrix.arch }} with ${{ matrix.toolchain_full }} + needs: set-matrix + runs-on: ${{ matrix.runs_on }} + timeout-minutes: 100 + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.set-matrix.outputs.build-matrix) }} + env: + KERNEL: ${{ matrix.kernel }} + REPO_ROOT: ${{ github.workspace }} + REPO_PATH: "" + KBUILD_OUTPUT: kbuild-output/ + steps: + - uses: actions/checkout@v3 + # We fetch an actual bit of history here to facilitate incremental + # builds (which may check out some earlier upstream change). + with: + fetch-depth: 50 + - if: ${{ github.repository == 'kernel-patches/vmtest' }} + name: Download bpf-next tree + uses: libbpf/ci/get-linux-source@main + with: + dest: '.kernel' + - if: ${{ github.repository == 'kernel-patches/vmtest' }} + name: Move linux source in place + shell: bash + run: | + rm -rf .kernel/.git + cp -rf .kernel/. . + rm -rf .kernel + - name: Get commit meta-data + id: get-commit-metadata + run: | + bash .github/scripts/get-commit-metadata.sh + - name: Pull recent KBUILD_OUTPUT contents + uses: actions/cache@v3 + with: + path: ${{ env.KBUILD_OUTPUT }} + key: kbuild-output-${{ matrix.arch }}-${{ matrix.toolchain_full }}-${{ steps.get-commit-metadata.outputs.branch }}-${{ steps.get-commit-metadata.outputs.timestamp }}-${{ steps.get-commit-metadata.outputs.commit }} + restore-keys: | + kbuild-output-${{ matrix.arch }}-${{ matrix.toolchain_full }}-${{ steps.get-commit-metadata.outputs.branch }}-${{ steps.get-commit-metadata.outputs.timestamp }}- + kbuild-output-${{ matrix.arch }}-${{ matrix.toolchain_full }}-${{ steps.get-commit-metadata.outputs.branch }}- + kbuild-output-${{ matrix.arch }}-${{ matrix.toolchain_full }}- + - name: Prepare incremental build + shell: bash + run: | + bash .github/scripts/prepare-incremental-builds.sh ${{ steps.get-commit-metadata.outputs.commit }} + - uses: libbpf/ci/patch-kernel@main + with: + patches-root: '${{ github.workspace }}/ci/diffs' + repo-root: '${{ github.workspace }}' + - name: Setup build environment + uses: libbpf/ci/setup-build-env@main + with: + llvm-version: ${{ matrix.llvm-version }} + - name: Build kernel image + uses: libbpf/ci/build-linux@main + with: + arch: ${{ matrix.arch }} + toolchain: ${{ matrix.toolchain }} + kbuild-output: ${{ env.KBUILD_OUTPUT }} + max-make-jobs: 32 + llvm-version: ${{ matrix.llvm-version }} + - name: Build selftests + uses: libbpf/ci/build-selftests@main + with: + toolchain: ${{ matrix.toolchain }} + kbuild-output: ${{ env.KBUILD_OUTPUT }} + max-make-jobs: 32 + llvm-version: ${{ matrix.llvm-version }} + - if: ${{ github.event_name != 'push' }} + name: Build samples + uses: libbpf/ci/build-samples@main + with: + toolchain: ${{ matrix.toolchain }} + kbuild-output: ${{ env.KBUILD_OUTPUT }} + max-make-jobs: 32 + llvm-version: ${{ matrix.llvm-version }} + - name: Tar artifacts + run: | + bash .github/scripts/tar-artifact.sh ${{ matrix.arch }} ${{ matrix.toolchain_full }} + - if: ${{ github.event_name != 'push' }} + name: Remove KBUILD_OUTPUT content + shell: bash + run: | + # Remove $KBUILD_OUTPUT to prevent cache creation for pull requests. + # Only on pushed changes are build artifacts actually cached, because + # of github.com/actions/cache's cache isolation logic. + rm -rf "${KBUILD_OUTPUT}" + - uses: actions/upload-artifact@v3 + with: + name: vmlinux-${{ matrix.arch }}-${{ matrix.toolchain_full }} + if-no-files-found: error + path: vmlinux-${{ matrix.arch }}-${{ matrix.toolchain_full }}.tar.zst + test: + if: ${{ github.event_name != 'push' }} + name: ${{ matrix.test }} on ${{ matrix.arch }} with ${{ matrix.toolchain_full }} + needs: [set-matrix, build] + strategy: + fail-fast: false + matrix: ${{ fromJSON(needs.set-matrix.outputs.test-matrix) }} + runs-on: ${{ matrix.runs_on }} + timeout-minutes: 100 + env: + KERNEL: ${{ matrix.kernel }} + REPO_ROOT: ${{ github.workspace }} + REPO_PATH: "" + KBUILD_OUTPUT: kbuild-output/ + steps: + - uses: actions/checkout@v3 + - uses: actions/download-artifact@v3 + with: + name: vmlinux-${{ matrix.arch }}-${{ matrix.toolchain_full }} + path: . + - name: Untar artifacts + # zstd is installed by default in the runner images. + run: zstd -d -T0 vmlinux-${{ matrix.arch }}-${{ matrix.toolchain_full }}.tar.zst --stdout | tar -xf - + - name: Prepare rootfs + uses: libbpf/ci/prepare-rootfs@main + with: + project-name: 'libbpf' + arch: ${{ matrix.arch }} + kernel: ${{ matrix.kernel }} + kernel-root: '.' + kbuild-output: ${{ env.KBUILD_OUTPUT }} + image-output: '/tmp/root.img' + test: ${{ matrix.test }} + - name: Run selftests + uses: libbpf/ci/run-qemu@main + continue-on-error: ${{ matrix.continue_on_error }} + timeout-minutes: ${{ matrix.timeout_minutes }} + with: + arch: ${{ matrix.arch}} + img: '/tmp/root.img' + vmlinuz: '${{ github.workspace }}/vmlinuz' + kernel-root: '.' + max-cpu: 8 + kernel-test: ${{ matrix.test }} + veristat: + name: veristat + needs: [set-matrix, build] + runs-on: ${{ fromJSON(needs.set-matrix.outputs.veristat-runs-on) }} + timeout-minutes: 100 + env: + KERNEL: LATEST + REPO_ROOT: ${{ github.workspace }} + REPO_PATH: "" + KBUILD_OUTPUT: kbuild-output/ + permissions: + id-token: write + contents: read + steps: + - name: Setup environment variables + run: | + echo ARCH_AND_TOOL=${{ env.veristat_arch }}-${{ env.veristat_toolchain }} >> \ + ${GITHUB_ENV} + - uses: actions/checkout@v3 + - uses: actions/download-artifact@v3 + with: + name: vmlinux-${{ env.ARCH_AND_TOOL }} + path: . + - name: Untar artifacts + # zstd is installed by default in the runner images. + run: zstd -d -T0 vmlinux-${{ env.ARCH_AND_TOOL }}.tar.zst --stdout | tar -xf - + + - name: Prepare rootfs + uses: libbpf/ci/prepare-rootfs@main + with: + project-name: 'libbpf' + arch: x86_64 + kernel: LATEST + kernel-root: '.' + kbuild-output: ${{ env.KBUILD_OUTPUT }} + image-output: '/tmp/root.img' + + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-region: ${{ vars.AWS_REGION }} + role-to-assume: ${{ secrets.AWS_ROLE_ARN }} + role-session-name: github-action-bpf-ci + + - name: Download BPF objects + run: | + set -eux + if [ -n "$AWS_ROLE_ARN" ]; then + mkdir /tmp/bpf_objects + aws s3 sync s3://veristat-bpf-binaries /tmp/bpf_objects + fi + env: + AWS_ROLE_ARN: ${{ secrets.AWS_ROLE_ARN }} + + - name: Add BPF objects to rootfs + shell: bash + run: ./.github/scripts/bpf-objects-rootfs.sh + + - name: Run veristat + uses: libbpf/ci/run-qemu@main + with: + arch: x86_64 + img: '/tmp/root.img' + vmlinuz: '${{ github.workspace }}/vmlinuz' + kernel-root: '.' + max-cpu: 8 + kernel-test: run_veristat_kernel,run_veristat_meta + output-dir: '${{ github.workspace }}' + + - name: Compare and save veristat.kernel.csv + uses: ./.github/actions/veristat_baseline_compare + with: + veristat_output: veristat-kernel + baseline_name: ${{ env.ARCH_AND_TOOL}}-baseline-veristat-kernel + + - name: Compare and save veristat.meta.csv + uses: ./.github/actions/veristat_baseline_compare + with: + veristat_output: veristat-meta + baseline_name: ${{ env.ARCH_AND_TOOL}}-baseline-veristat-meta diff --git a/README b/README index 669ac7c322927..e69de29bb2d1d 100644 --- a/README +++ b/README @@ -1,18 +0,0 @@ -Linux kernel -============ - -There are several guides for kernel developers and users. These guides can -be rendered in a number of formats, like HTML and PDF. Please read -Documentation/admin-guide/README.rst first. - -In order to build the documentation, use ``make htmldocs`` or -``make pdfdocs``. The formatted documentation can also be read online at: - - https://www.kernel.org/doc/html/latest/ - -There are various text files in the Documentation/ subdirectory, -several of them using the Restructured Text markup notation. - -Please read the Documentation/process/changes.rst file, as it contains the -requirements for building and running the kernel, and information about -the problems which may result by upgrading your kernel. diff --git a/ci/diffs/.keep b/ci/diffs/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/ci/diffs/0001-Revert-arch-fix-broken-BuildID-for-arm64-and-riscv.patch b/ci/diffs/0001-Revert-arch-fix-broken-BuildID-for-arm64-and-riscv.patch new file mode 100644 index 0000000000000..3d8ea87a1dbda --- /dev/null +++ b/ci/diffs/0001-Revert-arch-fix-broken-BuildID-for-arm64-and-riscv.patch @@ -0,0 +1,30 @@ +From cb50dac513235c6996b9d26f959886ba1d7be607 Mon Sep 17 00:00:00 2001 +From: Eduard Zingerman +Date: Fri, 6 Jan 2023 13:59:26 +0200 +Subject: [PATCH] Revert "arch: fix broken BuildID for arm64 and riscv" + +This reverts commit 99cb0d917ffa1ab628bb67364ca9b162c07699b1. +--- + include/asm-generic/vmlinux.lds.h | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h +index 659bf3b31c91..a94219e9916f 100644 +--- a/include/asm-generic/vmlinux.lds.h ++++ b/include/asm-generic/vmlinux.lds.h +@@ -891,12 +891,7 @@ + #define PRINTK_INDEX + #endif + +-/* +- * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler. +- * Otherwise, the type of .notes section would become PROGBITS instead of NOTES. +- */ + #define NOTES \ +- /DISCARD/ : { *(.note.GNU-stack) } \ + .notes : AT(ADDR(.notes) - LOAD_OFFSET) { \ + BOUNDED_SECTION_BY(.note.*, _notes) \ + } NOTES_HEADERS \ +-- +2.39.0 + diff --git a/ci/diffs/0001-bpf-Add-missing-btf_put-to-register_btf_id_dtor_kfun.patch b/ci/diffs/0001-bpf-Add-missing-btf_put-to-register_btf_id_dtor_kfun.patch new file mode 100644 index 0000000000000..4fcc0146effc3 --- /dev/null +++ b/ci/diffs/0001-bpf-Add-missing-btf_put-to-register_btf_id_dtor_kfun.patch @@ -0,0 +1,41 @@ +From 74bc3a5acc82f020d2e126f56c535d02d1e74e37 Mon Sep 17 00:00:00 2001 +From: Jiri Olsa +Date: Fri, 20 Jan 2023 13:21:48 +0100 +Subject: [PATCH] bpf: Add missing btf_put to register_btf_id_dtor_kfuncs + +We take the BTF reference before we register dtors and we need +to put it back when it's done. + +We probably won't se a problem with kernel BTF, but module BTF +would stay loaded (because of the extra ref) even when its module +is removed. + +Cc: Kumar Kartikeya Dwivedi +Fixes: 5ce937d613a4 ("bpf: Populate pairs of btf_id and destructor kfunc in btf") +Acked-by: Kumar Kartikeya Dwivedi +Signed-off-by: Jiri Olsa +Link: https://lore.kernel.org/r/20230120122148.1522359-1-jolsa@kernel.org +Signed-off-by: Alexei Starovoitov +--- + kernel/bpf/btf.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c +index f7dd8af06413..b7017cae6fd1 100644 +--- a/kernel/bpf/btf.c ++++ b/kernel/bpf/btf.c +@@ -7782,9 +7782,9 @@ int register_btf_id_dtor_kfuncs(const struct btf_id_dtor_kfunc *dtors, u32 add_c + + sort(tab->dtors, tab->cnt, sizeof(tab->dtors[0]), btf_id_cmp_func, NULL); + +- return 0; + end: +- btf_free_dtor_kfunc_tab(btf); ++ if (ret) ++ btf_free_dtor_kfunc_tab(btf); + btf_put(btf); + return ret; + } +-- +2.39.1 + diff --git a/ci/diffs/0001-bpf-Clarify-error-expectations-from-bpf_clone_redire.patch b/ci/diffs/0001-bpf-Clarify-error-expectations-from-bpf_clone_redire.patch new file mode 100644 index 0000000000000..1a2b1c0b2ddde --- /dev/null +++ b/ci/diffs/0001-bpf-Clarify-error-expectations-from-bpf_clone_redire.patch @@ -0,0 +1,58 @@ +From 7cb779a6867fea00b4209bcf6de2f178a743247d Mon Sep 17 00:00:00 2001 +From: Stanislav Fomichev +Date: Mon, 11 Sep 2023 12:47:30 -0700 +Subject: [PATCH 1/2] bpf: Clarify error expectations from bpf_clone_redirect + +Commit 151e887d8ff9 ("veth: Fixing transmit return status for dropped +packets") exposed the fact that bpf_clone_redirect is capable of +returning raw NET_XMIT_XXX return codes. + +This is in the conflict with its UAPI doc which says the following: +"0 on success, or a negative error in case of failure." + +Update the UAPI to reflect the fact that bpf_clone_redirect can +return positive error numbers, but don't explicitly define +their meaning. + +Reported-by: Daniel Borkmann +Signed-off-by: Stanislav Fomichev +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20230911194731.286342-1-sdf@google.com +--- + include/uapi/linux/bpf.h | 4 +++- + tools/include/uapi/linux/bpf.h | 4 +++- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h +index 8790b3962e4b..0448700890f7 100644 +--- a/include/uapi/linux/bpf.h ++++ b/include/uapi/linux/bpf.h +@@ -1962,7 +1962,9 @@ union bpf_attr { + * performed again, if the helper is used in combination with + * direct packet access. + * Return +- * 0 on success, or a negative error in case of failure. ++ * 0 on success, or a negative error in case of failure. Positive ++ * error indicates a potential drop or congestion in the target ++ * device. The particular positive error codes are not defined. + * + * u64 bpf_get_current_pid_tgid(void) + * Description +diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h +index 8790b3962e4b..0448700890f7 100644 +--- a/tools/include/uapi/linux/bpf.h ++++ b/tools/include/uapi/linux/bpf.h +@@ -1962,7 +1962,9 @@ union bpf_attr { + * performed again, if the helper is used in combination with + * direct packet access. + * Return +- * 0 on success, or a negative error in case of failure. ++ * 0 on success, or a negative error in case of failure. Positive ++ * error indicates a potential drop or congestion in the target ++ * device. The particular positive error codes are not defined. + * + * u64 bpf_get_current_pid_tgid(void) + * Description +-- +2.34.1 + diff --git a/ci/diffs/0001-bpf-Include-missing-nospec.h-to-avoid-build-error.patch b/ci/diffs/0001-bpf-Include-missing-nospec.h-to-avoid-build-error.patch new file mode 100644 index 0000000000000..669bde57d04f0 --- /dev/null +++ b/ci/diffs/0001-bpf-Include-missing-nospec.h-to-avoid-build-error.patch @@ -0,0 +1,45 @@ +From 345d24a91c79f408e355c8b7e873ccde0f097eea Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Wed, 22 Feb 2023 10:50:48 +0800 +Subject: [PATCH] bpf: Include missing nospec.h to avoid build error. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Commit 74e19ef0ff80 ("uaccess: Add speculation barrier to copy_from_user()") +defines a default barrier_nospec() and removes the +such a build error: + + CC kernel/bpf/core.o +kernel/bpf/core.c: In function ‘___bpf_prog_run’: +kernel/bpf/core.c:1913:3: error: implicit declaration of function ‘barrier_nospec’; did you mean ‘barrier_data’? [-Werror=implicit-function-declaration] + barrier_nospec(); + ^~~~~~~~~~~~~~ + barrier_data +cc1: some warnings being treated as errors + +So include nospec.h to avoid the build error. + +Fixes: 74e19ef0ff80 ("uaccess: Add speculation barrier to copy_from_user()") +Signed-off-by: Huacai Chen +Link: https://lore.kernel.org/r/20230222025048.3677315-1-chenhuacai@loongson.cn +Signed-off-by: Alexei Starovoitov +--- + kernel/bpf/core.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c +index 933869983e2a..b297e9f60ca1 100644 +--- a/kernel/bpf/core.c ++++ b/kernel/bpf/core.c +@@ -34,6 +34,7 @@ + #include + #include + #include ++#include + #include + #include + +-- +2.30.2 + diff --git a/ci/diffs/0001-bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch b/ci/diffs/0001-bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch new file mode 100644 index 0000000000000..bfb7de10b4793 --- /dev/null +++ b/ci/diffs/0001-bpftool-Fix-NULL-pointer-dereference-when-pin-PROG-M.patch @@ -0,0 +1,45 @@ +From 0dd340f3549863e1289a872057743c9a177d1e3f Mon Sep 17 00:00:00 2001 +From: Pu Lehui +Date: Wed, 2 Nov 2022 16:40:34 +0800 +Subject: [PATCH 1/2] bpftool: Fix NULL pointer dereference when pin {PROG, + MAP, LINK} without FILE + +When using bpftool to pin {PROG, MAP, LINK} without FILE, +segmentation fault will occur. The reson is that the lack +of FILE will cause strlen to trigger NULL pointer dereference. +The corresponding stacktrace is shown below: + +do_pin + do_pin_any + do_pin_fd + mount_bpffs_for_pin + strlen(name) <- NULL pointer dereference + +Fix it by adding validation to the common process. + +Fixes: 75a1e792c335 ("tools: bpftool: Allow all prog/map handles for pinning objects") +Signed-off-by: Pu Lehui +Signed-off-by: Daniel Borkmann +Reviewed-by: Quentin Monnet +Link: https://lore.kernel.org/bpf/20221102084034.3342995-1-pulehui@huaweicloud.com +--- + tools/bpf/bpftool/common.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c +index e4d33bc8bbbf..653c130a0aaa 100644 +--- a/tools/bpf/bpftool/common.c ++++ b/tools/bpf/bpftool/common.c +@@ -302,6 +302,9 @@ int do_pin_any(int argc, char **argv, int (*get_fd)(int *, char ***)) + int err; + int fd; + ++ if (!REQ_ARGS(3)) ++ return -EINVAL; ++ + fd = get_fd(&argc, &argv); + if (fd < 0) + return fd; +-- +2.30.2 + diff --git a/ci/diffs/0001-libbpf-btf_dump_type_data_check_overflow-needs-to-co.patch b/ci/diffs/0001-libbpf-btf_dump_type_data_check_overflow-needs-to-co.patch new file mode 100644 index 0000000000000..1b8842db87594 --- /dev/null +++ b/ci/diffs/0001-libbpf-btf_dump_type_data_check_overflow-needs-to-co.patch @@ -0,0 +1,115 @@ +From c39028b333f3a3a765c5c0b9726b8e38aedf0ba1 Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Thu, 27 Apr 2023 18:36:38 -0700 +Subject: [PATCH] libbpf: btf_dump_type_data_check_overflow needs to consider + BTF_MEMBER_BITFIELD_SIZE + +The btf_dump/struct_data selftest is failing with: + + [...] + test_btf_dump_struct_data:FAIL:unexpected return value dumping fs_context unexpected unexpected return value dumping fs_context: actual -7 != expected 264 + [...] + +The reason is in btf_dump_type_data_check_overflow(). It does not use +BTF_MEMBER_BITFIELD_SIZE from the struct's member (btf_member). Instead, +it is using the enum size which is 4. It had been working till the recent +commit 4e04143c869c ("fs_context: drop the unused lsm_flags member") +removed an integer member which also removed the 4 bytes padding at the +end of the fs_context. Missing this 4 bytes padding exposed this bug. In +particular, when btf_dump_type_data_check_overflow() reaches the member +'phase', -E2BIG is returned. + +The fix is to pass bit_sz to btf_dump_type_data_check_overflow(). In +btf_dump_type_data_check_overflow(), it does a different size check when +bit_sz is not zero. + +The current fs_context: + +[3600] ENUM 'fs_context_purpose' encoding=UNSIGNED size=4 vlen=3 + 'FS_CONTEXT_FOR_MOUNT' val=0 + 'FS_CONTEXT_FOR_SUBMOUNT' val=1 + 'FS_CONTEXT_FOR_RECONFIGURE' val=2 +[3601] ENUM 'fs_context_phase' encoding=UNSIGNED size=4 vlen=7 + 'FS_CONTEXT_CREATE_PARAMS' val=0 + 'FS_CONTEXT_CREATING' val=1 + 'FS_CONTEXT_AWAITING_MOUNT' val=2 + 'FS_CONTEXT_AWAITING_RECONF' val=3 + 'FS_CONTEXT_RECONF_PARAMS' val=4 + 'FS_CONTEXT_RECONFIGURING' val=5 + 'FS_CONTEXT_FAILED' val=6 +[3602] STRUCT 'fs_context' size=264 vlen=21 + 'ops' type_id=3603 bits_offset=0 + 'uapi_mutex' type_id=235 bits_offset=64 + 'fs_type' type_id=872 bits_offset=1216 + 'fs_private' type_id=21 bits_offset=1280 + 'sget_key' type_id=21 bits_offset=1344 + 'root' type_id=781 bits_offset=1408 + 'user_ns' type_id=251 bits_offset=1472 + 'net_ns' type_id=984 bits_offset=1536 + 'cred' type_id=1785 bits_offset=1600 + 'log' type_id=3621 bits_offset=1664 + 'source' type_id=42 bits_offset=1792 + 'security' type_id=21 bits_offset=1856 + 's_fs_info' type_id=21 bits_offset=1920 + 'sb_flags' type_id=20 bits_offset=1984 + 'sb_flags_mask' type_id=20 bits_offset=2016 + 's_iflags' type_id=20 bits_offset=2048 + 'purpose' type_id=3600 bits_offset=2080 bitfield_size=8 + 'phase' type_id=3601 bits_offset=2088 bitfield_size=8 + 'need_free' type_id=67 bits_offset=2096 bitfield_size=1 + 'global' type_id=67 bits_offset=2097 bitfield_size=1 + 'oldapi' type_id=67 bits_offset=2098 bitfield_size=1 + +Fixes: 920d16af9b42 ("libbpf: BTF dumper support for typed data") +Signed-off-by: Martin KaFai Lau +Signed-off-by: Daniel Borkmann +Acked-by: Yonghong Song +Link: https://lore.kernel.org/bpf/20230428013638.1581263-1-martin.lau@linux.dev +--- + tools/lib/bpf/btf_dump.c | 22 +++++++++++++++++++--- + 1 file changed, 19 insertions(+), 3 deletions(-) + +diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c +index 580985ee5545..4d9f30bf7f01 100644 +--- a/tools/lib/bpf/btf_dump.c ++++ b/tools/lib/bpf/btf_dump.c +@@ -2250,9 +2250,25 @@ static int btf_dump_type_data_check_overflow(struct btf_dump *d, + const struct btf_type *t, + __u32 id, + const void *data, +- __u8 bits_offset) ++ __u8 bits_offset, ++ __u8 bit_sz) + { +- __s64 size = btf__resolve_size(d->btf, id); ++ __s64 size; ++ ++ if (bit_sz) { ++ /* bits_offset is at most 7. bit_sz is at most 128. */ ++ __u8 nr_bytes = (bits_offset + bit_sz + 7) / 8; ++ ++ /* When bit_sz is non zero, it is called from ++ * btf_dump_struct_data() where it only cares about ++ * negative error value. ++ * Return nr_bytes in success case to make it ++ * consistent as the regular integer case below. ++ */ ++ return data + nr_bytes > d->typed_dump->data_end ? -E2BIG : nr_bytes; ++ } ++ ++ size = btf__resolve_size(d->btf, id); + + if (size < 0 || size >= INT_MAX) { + pr_warn("unexpected size [%zu] for id [%u]\n", +@@ -2407,7 +2423,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d, + { + int size, err = 0; + +- size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset); ++ size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset, bit_sz); + if (size < 0) + return size; + err = btf_dump_type_data_check_zero(d, t, id, data, bits_offset, bit_sz); +-- +2.34.1 + diff --git a/ci/diffs/0001-samples-bpf-drop-unnecessary-fallthrough.patch b/ci/diffs/0001-samples-bpf-drop-unnecessary-fallthrough.patch new file mode 100644 index 0000000000000..bb02a27e1592a --- /dev/null +++ b/ci/diffs/0001-samples-bpf-drop-unnecessary-fallthrough.patch @@ -0,0 +1,32 @@ +From f23a4ed043dfd36b758e627bdb30fc8e686f330d Mon Sep 17 00:00:00 2001 +From: Andrii Nakryiko +Date: Mon, 15 May 2023 13:00:20 -0700 +Subject: [PATCH bpf] samples/bpf: drop unnecessary fallthrough + +__fallthrough is now not supported. Instead of renaming it to +now-canonical ([0]) fallthrough pseudo-keyword, just get rid of it and +equate 'h' case to default case, as both emit usage information and +succeed. + + [0] https://www.kernel.org/doc/html/latest/process/deprecated.html?highlight=fallthrough#implicit-switch-case-fall-through + +Signed-off-by: Andrii Nakryiko +--- + samples/bpf/hbm.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/samples/bpf/hbm.c b/samples/bpf/hbm.c +index 6448b7826107..bf66277115e2 100644 +--- a/samples/bpf/hbm.c ++++ b/samples/bpf/hbm.c +@@ -498,7 +498,6 @@ int main(int argc, char **argv) + "Option -%c requires an argument.\n\n", + optopt); + case 'h': +- __fallthrough; + default: + Usage(); + return 0; +-- +2.34.1 + diff --git a/ci/diffs/0001-selftests-bpf-Add-config.aarch64.patch b/ci/diffs/0001-selftests-bpf-Add-config.aarch64.patch new file mode 100644 index 0000000000000..1797384c1b5c8 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Add-config.aarch64.patch @@ -0,0 +1,207 @@ +From ec99451f0a488e50aaf0ce467db8771411edc407 Mon Sep 17 00:00:00 2001 +From: Manu Bretelle +Date: Fri, 21 Oct 2022 14:06:59 -0700 +Subject: [PATCH] selftests/bpf: Add config.aarch64 + +config.aarch64, similarly to config.{s390x,x86_64} is a config enabling +building a kernel on aarch64 to be used in bpf's +selftests/kernel-patches CI. + +Signed-off-by: Manu Bretelle +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20221021210701.728135-3-chantr4@gmail.com +--- + tools/testing/selftests/bpf/config.aarch64 | 181 +++++++++++++++++++++ + 1 file changed, 181 insertions(+) + create mode 100644 tools/testing/selftests/bpf/config.aarch64 + +diff --git a/tools/testing/selftests/bpf/config.aarch64 b/tools/testing/selftests/bpf/config.aarch64 +new file mode 100644 +index 000000000000..1f0437644186 +--- /dev/null ++++ b/tools/testing/selftests/bpf/config.aarch64 +@@ -0,0 +1,181 @@ ++CONFIG_9P_FS=y ++CONFIG_ARCH_VEXPRESS=y ++CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y ++CONFIG_ARM_SMMU_V3=y ++CONFIG_ATA=y ++CONFIG_AUDIT=y ++CONFIG_BINFMT_MISC=y ++CONFIG_BLK_CGROUP=y ++CONFIG_BLK_DEV_BSGLIB=y ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_BLK_DEV_IO_TRACE=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_BONDING=y ++CONFIG_BPFILTER=y ++CONFIG_BPF_JIT_ALWAYS_ON=y ++CONFIG_BPF_JIT_DEFAULT_ON=y ++CONFIG_BPF_PRELOAD_UMD=y ++CONFIG_BPF_PRELOAD=y ++CONFIG_BRIDGE=m ++CONFIG_CGROUP_CPUACCT=y ++CONFIG_CGROUP_DEVICE=y ++CONFIG_CGROUP_FREEZER=y ++CONFIG_CGROUP_HUGETLB=y ++CONFIG_CGROUP_NET_CLASSID=y ++CONFIG_CGROUP_PERF=y ++CONFIG_CGROUP_PIDS=y ++CONFIG_CGROUP_SCHED=y ++CONFIG_CGROUPS=y ++CONFIG_CHECKPOINT_RESTORE=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_COMPAT=y ++CONFIG_CPUSETS=y ++CONFIG_CRASH_DUMP=y ++CONFIG_CRYPTO_USER_API_RNG=y ++CONFIG_CRYPTO_USER_API_SKCIPHER=y ++CONFIG_DEBUG_ATOMIC_SLEEP=y ++CONFIG_DEBUG_INFO_BTF=y ++CONFIG_DEBUG_INFO_DWARF4=y ++CONFIG_DEBUG_LIST=y ++CONFIG_DEBUG_LOCKDEP=y ++CONFIG_DEBUG_NOTIFIERS=y ++CONFIG_DEBUG_PAGEALLOC=y ++CONFIG_DEBUG_SECTION_MISMATCH=y ++CONFIG_DEBUG_SG=y ++CONFIG_DETECT_HUNG_TASK=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DEVTMPFS=y ++CONFIG_DRM_VIRTIO_GPU=y ++CONFIG_DRM=y ++CONFIG_DUMMY=y ++CONFIG_EXPERT=y ++CONFIG_EXT4_FS_POSIX_ACL=y ++CONFIG_EXT4_FS_SECURITY=y ++CONFIG_EXT4_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_FB=y ++CONFIG_FUNCTION_PROFILER=y ++CONFIG_FUSE_FS=y ++CONFIG_FW_CFG_SYSFS_CMDLINE=y ++CONFIG_FW_CFG_SYSFS=y ++CONFIG_GDB_SCRIPTS=y ++CONFIG_HAVE_EBPF_JIT=y ++CONFIG_HAVE_KPROBES_ON_FTRACE=y ++CONFIG_HAVE_KPROBES=y ++CONFIG_HAVE_KRETPROBES=y ++CONFIG_HEADERS_INSTALL=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_HUGETLBFS=y ++CONFIG_HW_RANDOM_VIRTIO=y ++CONFIG_HW_RANDOM=y ++CONFIG_HZ_100=y ++CONFIG_IDLE_PAGE_TRACKING=y ++CONFIG_IKHEADERS=y ++CONFIG_INET6_ESP=y ++CONFIG_INET_ESP=y ++CONFIG_INET=y ++CONFIG_INPUT_EVDEV=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IPV6_SEG6_LWTUNNEL=y ++CONFIG_IPVLAN=y ++CONFIG_JUMP_LABEL=y ++CONFIG_KERNEL_UNCOMPRESSED=y ++CONFIG_KPROBES_ON_FTRACE=y ++CONFIG_KPROBES=y ++CONFIG_KRETPROBES=y ++CONFIG_KSM=y ++CONFIG_LATENCYTOP=y ++CONFIG_LIVEPATCH=y ++CONFIG_LOCK_STAT=y ++CONFIG_MACVLAN=y ++CONFIG_MACVTAP=y ++CONFIG_MAGIC_SYSRQ=y ++CONFIG_MAILBOX=y ++CONFIG_MEMCG=y ++CONFIG_MEMORY_HOTPLUG=y ++CONFIG_MEMORY_HOTREMOVE=y ++CONFIG_NAMESPACES=y ++CONFIG_NET_9P_VIRTIO=y ++CONFIG_NET_9P=y ++CONFIG_NET_ACT_BPF=y ++CONFIG_NET_ACT_GACT=y ++CONFIG_NETDEVICES=y ++CONFIG_NETFILTER_XT_MATCH_BPF=y ++CONFIG_NETFILTER_XT_TARGET_MARK=y ++CONFIG_NET_KEY=y ++CONFIG_NET_SCH_FQ=y ++CONFIG_NET_VRF=y ++CONFIG_NET=y ++CONFIG_NF_TABLES=y ++CONFIG_NLMON=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_NR_CPUS=256 ++CONFIG_NUMA=y ++CONFIG_OVERLAY_FS=y ++CONFIG_PACKET_DIAG=y ++CONFIG_PACKET=y ++CONFIG_PANIC_ON_OOPS=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_PCI_HOST_GENERIC=y ++CONFIG_PCI=y ++CONFIG_PL320_MBOX=y ++CONFIG_POSIX_MQUEUE=y ++CONFIG_PROC_KCORE=y ++CONFIG_PROFILING=y ++CONFIG_PROVE_LOCKING=y ++CONFIG_PTDUMP_DEBUGFS=y ++CONFIG_RC_DEVICES=y ++CONFIG_RC_LOOPBACK=y ++CONFIG_RTC_CLASS=y ++CONFIG_RTC_DRV_PL031=y ++CONFIG_RT_GROUP_SCHED=y ++CONFIG_SAMPLE_SECCOMP=y ++CONFIG_SAMPLES=y ++CONFIG_SCHED_AUTOGROUP=y ++CONFIG_SCHED_TRACER=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_SCSI_SCAN_ASYNC=y ++CONFIG_SCSI_VIRTIO=y ++CONFIG_SCSI=y ++CONFIG_SECURITY_NETWORK=y ++CONFIG_SERIAL_AMBA_PL011_CONSOLE=y ++CONFIG_SERIAL_AMBA_PL011=y ++CONFIG_STACK_TRACER=y ++CONFIG_STATIC_KEYS_SELFTEST=y ++CONFIG_SYSVIPC=y ++CONFIG_TASK_DELAY_ACCT=y ++CONFIG_TASK_IO_ACCOUNTING=y ++CONFIG_TASKSTATS=y ++CONFIG_TASK_XACCT=y ++CONFIG_TCG_TIS=y ++CONFIG_TCG_TPM=y ++CONFIG_TCP_CONG_ADVANCED=y ++CONFIG_TCP_CONG_DCTCP=y ++CONFIG_TLS=y ++CONFIG_TMPFS_POSIX_ACL=y ++CONFIG_TMPFS=y ++CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y ++CONFIG_TRANSPARENT_HUGEPAGE=y ++CONFIG_TUN=y ++CONFIG_UNIX=y ++CONFIG_UPROBES=y ++CONFIG_USELIB=y ++CONFIG_USER_NS=y ++CONFIG_VETH=y ++CONFIG_VIRTIO_BALLOON=y ++CONFIG_VIRTIO_BLK=y ++CONFIG_VIRTIO_CONSOLE=y ++CONFIG_VIRTIO_FS=y ++CONFIG_VIRTIO_INPUT=y ++CONFIG_VIRTIO_MMIO_CMDLINE_DEVICES=y ++CONFIG_VIRTIO_MMIO=y ++CONFIG_VIRTIO_NET=y ++CONFIG_VIRTIO_PCI=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VSOCKETS=y ++CONFIG_XFRM_USER=y +-- +2.38.1 + diff --git a/ci/diffs/0001-selftests-bpf-Add-json-summary-option-to-test_progs.patch b/ci/diffs/0001-selftests-bpf-Add-json-summary-option-to-test_progs.patch new file mode 100644 index 0000000000000..ec424feb15c4e --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Add-json-summary-option-to-test_progs.patch @@ -0,0 +1,357 @@ +From 2be7aa76cc69633930fb747e1d85d33a63a60c02 Mon Sep 17 00:00:00 2001 +From: Manu Bretelle +Date: Fri, 17 Mar 2023 09:32:56 -0700 +Subject: [PATCH] selftests/bpf: Add --json-summary option to test_progs + +Currently, test_progs outputs all stdout/stderr as it runs, and when it +is done, prints a summary. + +It is non-trivial for tooling to parse that output and extract meaningful +information from it. + +This change adds a new option, `--json-summary`/`-J` that let the caller +specify a file where `test_progs{,-no_alu32}` can write a summary of the +run in a json format that can later be parsed by tooling. + +Currently, it creates a summary section with successes/skipped/failures +followed by a list of failed tests and subtests. + +A test contains the following fields: +- name: the name of the test +- number: the number of the test +- message: the log message that was printed by the test. +- failed: A boolean indicating whether the test failed or not. Currently +we only output failed tests, but in the future, successful tests could +be added. +- subtests: A list of subtests associated with this test. + +A subtest contains the following fields: +- name: same as above +- number: sanme as above +- message: the log message that was printed by the subtest. +- failed: same as above but for the subtest + +An example run and json content below: +``` +$ sudo ./test_progs -a $(grep -v '^#' ./DENYLIST.aarch64 | awk '{print +$1","}' | tr -d '\n') -j -J /tmp/test_progs.json +$ jq < /tmp/test_progs.json | head -n 30 +{ + "success": 29, + "success_subtest": 23, + "skipped": 3, + "failed": 28, + "results": [ + { + "name": "bpf_cookie", + "number": 10, + "message": "test_bpf_cookie:PASS:skel_open 0 nsec\n", + "failed": true, + "subtests": [ + { + "name": "multi_kprobe_link_api", + "number": 2, + "message": "kprobe_multi_link_api_subtest:PASS:load_kallsyms 0 nsec\nlibbpf: extern 'bpf_testmod_fentry_test1' (strong): not resolved\nlibbpf: failed to load object 'kprobe_multi'\nlibbpf: failed to load BPF skeleton 'kprobe_multi': -3\nkprobe_multi_link_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3\n", + "failed": true + }, + { + "name": "multi_kprobe_attach_api", + "number": 3, + "message": "libbpf: extern 'bpf_testmod_fentry_test1' (strong): not resolved\nlibbpf: failed to load object 'kprobe_multi'\nlibbpf: failed to load BPF skeleton 'kprobe_multi': -3\nkprobe_multi_attach_api_subtest:FAIL:fentry_raw_skel_load unexpected error: -3\n", + "failed": true + }, + { + "name": "lsm", + "number": 8, + "message": "lsm_subtest:PASS:lsm.link_create 0 nsec\nlsm_subtest:FAIL:stack_mprotect unexpected stack_mprotect: actual 0 != expected -1\n", + "failed": true + } +``` + +The file can then be used to print a summary of the test run and list of +failing tests/subtests: + +``` +$ jq -r < /tmp/test_progs.json '"Success: \(.success)/\(.success_subtest), Skipped: \(.skipped), Failed: \(.failed)"' + +Success: 29/23, Skipped: 3, Failed: 28 +$ jq -r < /tmp/test_progs.json '.results | map([ + if .failed then "#\(.number) \(.name)" else empty end, + ( + . as {name: $tname, number: $tnum} | .subtests | map( + if .failed then "#\($tnum)/\(.number) \($tname)/\(.name)" else empty end + ) + ) +]) | flatten | .[]' | head -n 20 + #10 bpf_cookie + #10/2 bpf_cookie/multi_kprobe_link_api + #10/3 bpf_cookie/multi_kprobe_attach_api + #10/8 bpf_cookie/lsm + #15 bpf_mod_race + #15/1 bpf_mod_race/ksym (used_btfs UAF) + #15/2 bpf_mod_race/kfunc (kfunc_btf_tab UAF) + #36 cgroup_hierarchical_stats + #61 deny_namespace + #61/1 deny_namespace/unpriv_userns_create_no_bpf + #73 fexit_stress + #83 get_func_ip_test + #99 kfunc_dynptr_param + #99/1 kfunc_dynptr_param/dynptr_data_null + #99/4 kfunc_dynptr_param/dynptr_data_null + #100 kprobe_multi_bench_attach + #100/1 kprobe_multi_bench_attach/kernel + #100/2 kprobe_multi_bench_attach/modules + #101 kprobe_multi_test + #101/1 kprobe_multi_test/skel_api +``` + +Signed-off-by: Manu Bretelle +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20230317163256.3809328-1-chantr4@gmail.com +--- + tools/testing/selftests/bpf/Makefile | 4 +- + tools/testing/selftests/bpf/json_writer.c | 1 + + tools/testing/selftests/bpf/json_writer.h | 1 + + tools/testing/selftests/bpf/test_progs.c | 83 +++++++++++++++++++++-- + tools/testing/selftests/bpf/test_progs.h | 1 + + 5 files changed, 84 insertions(+), 6 deletions(-) + create mode 120000 tools/testing/selftests/bpf/json_writer.c + create mode 120000 tools/testing/selftests/bpf/json_writer.h + +diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile +index b677dcd0b77a..59173eb636f5 100644 +--- a/tools/testing/selftests/bpf/Makefile ++++ b/tools/testing/selftests/bpf/Makefile +@@ -234,6 +234,7 @@ $(TEST_GEN_PROGS) $(TEST_GEN_PROGS_EXTENDED): $(BPFOBJ) + CGROUP_HELPERS := $(OUTPUT)/cgroup_helpers.o + TESTING_HELPERS := $(OUTPUT)/testing_helpers.o + TRACE_HELPERS := $(OUTPUT)/trace_helpers.o ++JSON_WRITER := $(OUTPUT)/json_writer.o + CAP_HELPERS := $(OUTPUT)/cap_helpers.o + + $(OUTPUT)/test_dev_cgroup: $(CGROUP_HELPERS) $(TESTING_HELPERS) +@@ -558,7 +559,8 @@ TRUNNER_BPF_PROGS_DIR := progs + TRUNNER_EXTRA_SOURCES := test_progs.c cgroup_helpers.c trace_helpers.c \ + network_helpers.c testing_helpers.c \ + btf_helpers.c flow_dissector_load.h \ +- cap_helpers.c test_loader.c xsk.c ++ cap_helpers.c test_loader.c xsk.c \ ++ json_writer.c + TRUNNER_EXTRA_FILES := $(OUTPUT)/urandom_read $(OUTPUT)/bpf_testmod.ko \ + $(OUTPUT)/liburandom_read.so \ + $(OUTPUT)/xdp_synproxy \ +diff --git a/tools/testing/selftests/bpf/json_writer.c b/tools/testing/selftests/bpf/json_writer.c +new file mode 120000 +index 000000000000..5effa31e2f39 +--- /dev/null ++++ b/tools/testing/selftests/bpf/json_writer.c +@@ -0,0 +1 @@ ++../../../bpf/bpftool/json_writer.c +\ No newline at end of file +diff --git a/tools/testing/selftests/bpf/json_writer.h b/tools/testing/selftests/bpf/json_writer.h +new file mode 120000 +index 000000000000..e0a264c26752 +--- /dev/null ++++ b/tools/testing/selftests/bpf/json_writer.h +@@ -0,0 +1 @@ ++../../../bpf/bpftool/json_writer.h +\ No newline at end of file +diff --git a/tools/testing/selftests/bpf/test_progs.c b/tools/testing/selftests/bpf/test_progs.c +index 6d5e3022c75f..d903e6a72a96 100644 +--- a/tools/testing/selftests/bpf/test_progs.c ++++ b/tools/testing/selftests/bpf/test_progs.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include "json_writer.h" + + static bool verbose(void) + { +@@ -269,10 +270,23 @@ static void print_subtest_name(int test_num, int subtest_num, + fprintf(env.stdout, "\n"); + } + ++static void jsonw_write_log_message(json_writer_t *w, char *log_buf, size_t log_cnt) ++{ ++ /* open_memstream (from stdio_hijack_init) ensures that log_bug is terminated by a ++ * null byte. Yet in parallel mode, log_buf will be NULL if there is no message. ++ */ ++ if (log_cnt) { ++ jsonw_string_field(w, "message", log_buf); ++ } else { ++ jsonw_string_field(w, "message", ""); ++ } ++} ++ + static void dump_test_log(const struct prog_test_def *test, + const struct test_state *test_state, + bool skip_ok_subtests, +- bool par_exec_result) ++ bool par_exec_result, ++ json_writer_t *w) + { + bool test_failed = test_state->error_cnt > 0; + bool force_log = test_state->force_log; +@@ -296,6 +310,16 @@ static void dump_test_log(const struct prog_test_def *test, + if (test_state->log_cnt && print_test) + print_test_log(test_state->log_buf, test_state->log_cnt); + ++ if (w && print_test) { ++ jsonw_start_object(w); ++ jsonw_string_field(w, "name", test->test_name); ++ jsonw_uint_field(w, "number", test->test_num); ++ jsonw_write_log_message(w, test_state->log_buf, test_state->log_cnt); ++ jsonw_bool_field(w, "failed", test_failed); ++ jsonw_name(w, "subtests"); ++ jsonw_start_array(w); ++ } ++ + for (i = 0; i < test_state->subtest_num; i++) { + subtest_state = &test_state->subtest_states[i]; + subtest_failed = subtest_state->error_cnt; +@@ -314,6 +338,20 @@ static void dump_test_log(const struct prog_test_def *test, + test->test_name, subtest_state->name, + test_result(subtest_state->error_cnt, + subtest_state->skipped)); ++ ++ if (w && print_subtest) { ++ jsonw_start_object(w); ++ jsonw_string_field(w, "name", subtest_state->name); ++ jsonw_uint_field(w, "number", i+1); ++ jsonw_write_log_message(w, subtest_state->log_buf, subtest_state->log_cnt); ++ jsonw_bool_field(w, "failed", subtest_failed); ++ jsonw_end_object(w); ++ } ++ } ++ ++ if (w && print_test) { ++ jsonw_end_array(w); ++ jsonw_end_object(w); + } + + print_test_result(test, test_state); +@@ -715,6 +753,7 @@ enum ARG_KEYS { + ARG_TEST_NAME_GLOB_DENYLIST = 'd', + ARG_NUM_WORKERS = 'j', + ARG_DEBUG = -1, ++ ARG_JSON_SUMMARY = 'J' + }; + + static const struct argp_option opts[] = { +@@ -740,6 +779,7 @@ static const struct argp_option opts[] = { + "Number of workers to run in parallel, default to number of cpus." }, + { "debug", ARG_DEBUG, NULL, 0, + "print extra debug information for test_progs." }, ++ { "json-summary", ARG_JSON_SUMMARY, "FILE", 0, "Write report in json format to this file."}, + {}, + }; + +@@ -870,6 +910,13 @@ static error_t parse_arg(int key, char *arg, struct argp_state *state) + case ARG_DEBUG: + env->debug = true; + break; ++ case ARG_JSON_SUMMARY: ++ env->json = fopen(arg, "w"); ++ if (env->json == NULL) { ++ perror("Failed to open json summary file"); ++ return -errno; ++ } ++ break; + case ARGP_KEY_ARG: + argp_usage(state); + break; +@@ -1017,7 +1064,7 @@ void crash_handler(int signum) + stdio_restore(); + if (env.test) { + env.test_state->error_cnt++; +- dump_test_log(env.test, env.test_state, true, false); ++ dump_test_log(env.test, env.test_state, true, false, NULL); + } + if (env.worker_id != -1) + fprintf(stderr, "[%d]: ", env.worker_id); +@@ -1124,7 +1171,7 @@ static void run_one_test(int test_num) + + stdio_restore(); + +- dump_test_log(test, state, false, false); ++ dump_test_log(test, state, false, false, NULL); + } + + struct dispatch_data { +@@ -1283,7 +1330,7 @@ static void *dispatch_thread(void *ctx) + } while (false); + + pthread_mutex_lock(&stdout_output_lock); +- dump_test_log(test, state, false, true); ++ dump_test_log(test, state, false, true, NULL); + pthread_mutex_unlock(&stdout_output_lock); + } /* while (true) */ + error: +@@ -1308,6 +1355,7 @@ static void calculate_summary_and_print_errors(struct test_env *env) + { + int i; + int succ_cnt = 0, fail_cnt = 0, sub_succ_cnt = 0, skip_cnt = 0; ++ json_writer_t *w = NULL; + + for (i = 0; i < prog_test_cnt; i++) { + struct test_state *state = &test_states[i]; +@@ -1324,6 +1372,22 @@ static void calculate_summary_and_print_errors(struct test_env *env) + succ_cnt++; + } + ++ if (env->json) { ++ w = jsonw_new(env->json); ++ if (!w) ++ fprintf(env->stderr, "Failed to create new JSON stream."); ++ } ++ ++ if (w) { ++ jsonw_start_object(w); ++ jsonw_uint_field(w, "success", succ_cnt); ++ jsonw_uint_field(w, "success_subtest", sub_succ_cnt); ++ jsonw_uint_field(w, "skipped", skip_cnt); ++ jsonw_uint_field(w, "failed", fail_cnt); ++ jsonw_name(w, "results"); ++ jsonw_start_array(w); ++ } ++ + /* + * We only print error logs summary when there are failed tests and + * verbose mode is not enabled. Otherwise, results may be incosistent. +@@ -1340,10 +1404,19 @@ static void calculate_summary_and_print_errors(struct test_env *env) + if (!state->tested || !state->error_cnt) + continue; + +- dump_test_log(test, state, true, true); ++ dump_test_log(test, state, true, true, w); + } + } + ++ if (w) { ++ jsonw_end_array(w); ++ jsonw_end_object(w); ++ jsonw_destroy(&w); ++ } ++ ++ if (env->json) ++ fclose(env->json); ++ + printf("Summary: %d/%d PASSED, %d SKIPPED, %d FAILED\n", + succ_cnt, sub_succ_cnt, skip_cnt, fail_cnt); + +diff --git a/tools/testing/selftests/bpf/test_progs.h b/tools/testing/selftests/bpf/test_progs.h +index 3cbf005747ed..4b06b8347cd4 100644 +--- a/tools/testing/selftests/bpf/test_progs.h ++++ b/tools/testing/selftests/bpf/test_progs.h +@@ -114,6 +114,7 @@ struct test_env { + FILE *stdout; + FILE *stderr; + int nr_cpus; ++ FILE *json; + + int succ_cnt; /* successful tests */ + int sub_succ_cnt; /* successful sub-tests */ +-- +2.39.2 + diff --git a/ci/diffs/0001-selftests-bpf-Adjust-expected-error-message-for-test.patch b/ci/diffs/0001-selftests-bpf-Adjust-expected-error-message-for-test.patch new file mode 100644 index 0000000000000..11d5233552b07 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Adjust-expected-error-message-for-test.patch @@ -0,0 +1,43 @@ +From fa95252a62bc120fb1f939c46991280ba1375196 Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Thu, 2 Mar 2023 13:49:44 -0800 +Subject: [PATCH] selftests/bpf: Adjust expected error message for + test_global_func10.c + +For test programs that are expected to be failed verifier, we use +__failure __msg(...) to specify the expected error message. However, the +error message may change slightly among different versions of llvm. For +example, in [1], the program compiled by llvm-17 gets + + "invalid indirect access to stack ..." + +but the same program compile by llvm-16 gets + + "invalid indirect read from stack ..." + +To avoid such issues, only compares "invalid indirect" part of the error +message for test_global_func10.c. + +[1] https://github.com/kernel-patches/bpf/actions/runs/4288572350/jobs/7533052993 + +Signed-off-by: Song Liu +--- + tools/testing/selftests/bpf/progs/test_global_func10.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/progs/test_global_func10.c b/tools/testing/selftests/bpf/progs/test_global_func10.c +index 98327bdbbfd2..7a591d946027 100644 +--- a/tools/testing/selftests/bpf/progs/test_global_func10.c ++++ b/tools/testing/selftests/bpf/progs/test_global_func10.c +@@ -22,7 +22,7 @@ __noinline int foo(const struct Big *big) + } + + SEC("cgroup_skb/ingress") +-__failure __msg("invalid indirect read from stack") ++__failure __msg("invalid indirect") + int global_func10(struct __sk_buff *skb) + { + const struct Small small = {.x = skb->len }; +-- +2.30.2 + diff --git a/ci/diffs/0001-selftests-bpf-Fix-compilation-errors-Assign-a-value-.patch b/ci/diffs/0001-selftests-bpf-Fix-compilation-errors-Assign-a-value-.patch new file mode 100644 index 0000000000000..14a62c2d5d6c8 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Fix-compilation-errors-Assign-a-value-.patch @@ -0,0 +1,50 @@ +From 11e456cae91e9044cb12c2b037b52c9b268925f7 Mon Sep 17 00:00:00 2001 +From: Rong Tao +Date: Fri, 24 Feb 2023 23:10:02 +0800 +Subject: [PATCH bpf] selftests/bpf: Fix compilation errors: Assign a value to + a constant + +Commit bc292ab00f6c("mm: introduce vma->vm_flags wrapper functions") +turns the vm_flags into a const variable. + +Added bpf_find_vma test in commit f108662b27c9("selftests/bpf: Add tests +for bpf_find_vma") to assign values to variables that declare const in +find_vma_fail1.c programs, which is an error to the compiler and does not +test BPF verifiers. It is better to replace 'const vm_flags_t vm_flags' +with 'unsigned long vm_start' for testing. + + $ make -C tools/testing/selftests/bpf/ -j8 + ... + progs/find_vma_fail1.c:16:16: error: cannot assign to non-static data + member 'vm_flags' with const-qualified type 'const vm_flags_t' (aka + 'const unsigned long') + vma->vm_flags |= 0x55; + ~~~~~~~~~~~~~ ^ + ../tools/testing/selftests/bpf/tools/include/vmlinux.h:1898:20: + note: non-static data member 'vm_flags' declared const here + const vm_flags_t vm_flags; + ~~~~~~~~~~~`~~~~~~^~~~~~~~ + +Signed-off-by: Rong Tao +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/tencent_CB281722B3C1BD504C16CDE586CACC2BE706@qq.com +--- + tools/testing/selftests/bpf/progs/find_vma_fail1.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/progs/find_vma_fail1.c b/tools/testing/selftests/bpf/progs/find_vma_fail1.c +index b3b326b8e2d1..47d5dedff554 100644 +--- a/tools/testing/selftests/bpf/progs/find_vma_fail1.c ++++ b/tools/testing/selftests/bpf/progs/find_vma_fail1.c +@@ -13,7 +13,7 @@ static long write_vma(struct task_struct *task, struct vm_area_struct *vma, + struct callback_ctx *data) + { + /* writing to vma, which is illegal */ +- vma->vm_flags |= 0x55; ++ vma->vm_start = 0xffffffffff600000; + + return 0; + } +-- +2.39.0 + diff --git a/ci/diffs/0001-selftests-bpf-Fix-decap_sanity_ns-cleanup.patch b/ci/diffs/0001-selftests-bpf-Fix-decap_sanity_ns-cleanup.patch new file mode 100644 index 0000000000000..41fd6e38e8678 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Fix-decap_sanity_ns-cleanup.patch @@ -0,0 +1,36 @@ +From: Ilya Leoshkevich +Subject: [PATCH bpf-next 07/24] selftests/bpf: Fix decap_sanity_ns cleanup +Date: Wed, 25 Jan 2023 22:38:00 +0100 + +decap_sanity prints the following on the 1st run: + + decap_sanity: sh: 1: Syntax error: Bad fd number + +and the following on the 2nd run: + + Cannot create namespace file "/run/netns/decap_sanity_ns": File exists + +The problem is that the cleanup command has a typo and does nothing. +Fix the typo. + +Signed-off-by: Ilya Leoshkevich +--- + tools/testing/selftests/bpf/prog_tests/decap_sanity.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/decap_sanity.c b/tools/testing/selftests/bpf/prog_tests/decap_sanity.c +index 0b2f73b88c53..2853883b7cbb 100644 +--- a/tools/testing/selftests/bpf/prog_tests/decap_sanity.c ++++ b/tools/testing/selftests/bpf/prog_tests/decap_sanity.c +@@ -80,6 +80,6 @@ void test_decap_sanity(void) + bpf_tc_hook_destroy(&qdisc_hook); + close_netns(nstoken); + } +- system("ip netns del " NS_TEST " >& /dev/null"); ++ system("ip netns del " NS_TEST " &> /dev/null"); + decap_sanity__destroy(skel); + } +-- +2.39.1 + + diff --git a/ci/diffs/0001-selftests-bpf-Initial-DENYLIST-for-aarch64.patch b/ci/diffs/0001-selftests-bpf-Initial-DENYLIST-for-aarch64.patch new file mode 100644 index 0000000000000..7d3a35de2a636 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Initial-DENYLIST-for-aarch64.patch @@ -0,0 +1,118 @@ +From 94d52a19180726ee8ddc70bea75d6605e1dd6029 Mon Sep 17 00:00:00 2001 +From: Manu Bretelle +Date: Fri, 21 Oct 2022 14:07:01 -0700 +Subject: [PATCH] selftests/bpf: Initial DENYLIST for aarch64 + +Those tests are currently failing on aarch64, ignore them until they are +individually addressed. + +Using this deny list, vmtest.sh ran successfully using + +LLVM_STRIP=llvm-strip-16 CLANG=clang-16 \ + tools/testing/selftests/bpf/vmtest.sh -- \ + ./test_progs -d \ + \"$(cat tools/testing/selftests/bpf/DENYLIST{,.aarch64} \ + | cut -d'#' -f1 \ + | sed -e 's/^[[:space:]]*//' \ + -e 's/[[:space:]]*$//' \ + | tr -s '\n' ','\ + )\" + +Signed-off-by: Manu Bretelle +Signed-off-by: Andrii Nakryiko +Link: https://lore.kernel.org/bpf/20221021210701.728135-5-chantr4@gmail.com +--- + tools/testing/selftests/bpf/DENYLIST.aarch64 | 81 ++++++++++++++++++++ + 1 file changed, 81 insertions(+) + create mode 100644 tools/testing/selftests/bpf/DENYLIST.aarch64 + +diff --git a/tools/testing/selftests/bpf/DENYLIST.aarch64 b/tools/testing/selftests/bpf/DENYLIST.aarch64 +new file mode 100644 +index 000000000000..09416d5d2e33 +--- /dev/null ++++ b/tools/testing/selftests/bpf/DENYLIST.aarch64 +@@ -0,0 +1,81 @@ ++bloom_filter_map # libbpf: prog 'check_bloom': failed to attach: ERROR: strerror_r(-524)=22 ++bpf_cookie/lsm ++bpf_cookie/multi_kprobe_attach_api ++bpf_cookie/multi_kprobe_link_api ++bpf_cookie/trampoline ++bpf_loop/check_callback_fn_stop # link unexpected error: -524 ++bpf_loop/check_invalid_flags ++bpf_loop/check_nested_calls ++bpf_loop/check_non_constant_callback ++bpf_loop/check_nr_loops ++bpf_loop/check_null_callback_ctx ++bpf_loop/check_stack ++bpf_mod_race # bpf_mod_kfunc_race__attach unexpected error: -524 (errno 524) ++bpf_tcp_ca/dctcp_fallback ++btf_dump/btf_dump: var_data # find type id unexpected find type id: actual -2 < expected 0 ++cgroup_hierarchical_stats # attach unexpected error: -524 (errno 524) ++d_path/basic # setup attach failed: -524 ++deny_namespace # attach unexpected error: -524 (errno 524) ++fentry_fexit # fentry_attach unexpected error: -1 (errno 524) ++fentry_test # fentry_attach unexpected error: -1 (errno 524) ++fexit_sleep # fexit_attach fexit attach failed: -1 ++fexit_stress # fexit attach unexpected fexit attach: actual -524 < expected 0 ++fexit_test # fexit_attach unexpected error: -1 (errno 524) ++get_func_args_test # get_func_args_test__attach unexpected error: -524 (errno 524) (trampoline) ++get_func_ip_test # get_func_ip_test__attach unexpected error: -524 (errno 524) (trampoline) ++htab_update/reenter_update ++kfree_skb # attach fentry unexpected error: -524 (trampoline) ++kfunc_call/subprog # extern (var ksym) 'bpf_prog_active': not found in kernel BTF ++kfunc_call/subprog_lskel # skel unexpected error: -2 ++kfunc_dynptr_param/dynptr_data_null # libbpf: prog 'dynptr_data_null': failed to attach: ERROR: strerror_r(-524)=22 ++kprobe_multi_test/attach_api_addrs # bpf_program__attach_kprobe_multi_opts unexpected error: -95 ++kprobe_multi_test/attach_api_pattern # bpf_program__attach_kprobe_multi_opts unexpected error: -95 ++kprobe_multi_test/attach_api_syms # bpf_program__attach_kprobe_multi_opts unexpected error: -95 ++kprobe_multi_test/bench_attach # bpf_program__attach_kprobe_multi_opts unexpected error: -95 ++kprobe_multi_test/link_api_addrs # link_fd unexpected link_fd: actual -95 < expected 0 ++kprobe_multi_test/link_api_syms # link_fd unexpected link_fd: actual -95 < expected 0 ++kprobe_multi_test/skel_api # kprobe_multi__attach unexpected error: -524 (errno 524) ++ksyms_module/libbpf # 'bpf_testmod_ksym_percpu': not found in kernel BTF ++ksyms_module/lskel # test_ksyms_module_lskel__open_and_load unexpected error: -2 ++libbpf_get_fd_by_id_opts # test_libbpf_get_fd_by_id_opts__attach unexpected error: -524 (errno 524) ++lookup_key # test_lookup_key__attach unexpected error: -524 (errno 524) ++lru_bug # lru_bug__attach unexpected error: -524 (errno 524) ++modify_return # modify_return__attach failed unexpected error: -524 (errno 524) ++module_attach # skel_attach skeleton attach failed: -524 ++mptcp/base # run_test mptcp unexpected error: -524 (errno 524) ++netcnt # packets unexpected packets: actual 10001 != expected 10000 ++recursion # skel_attach unexpected error: -524 (errno 524) ++ringbuf # skel_attach skeleton attachment failed: -1 ++setget_sockopt # attach_cgroup unexpected error: -524 ++sk_storage_tracing # test_sk_storage_tracing__attach unexpected error: -524 (errno 524) ++skc_to_unix_sock # could not attach BPF object unexpected error: -524 (errno 524) ++socket_cookie # prog_attach unexpected error: -524 ++stacktrace_build_id # compare_stack_ips stackmap vs. stack_amap err -1 errno 2 ++task_local_storage/exit_creds # skel_attach unexpected error: -524 (errno 524) ++task_local_storage/recursion # skel_attach unexpected error: -524 (errno 524) ++test_bprm_opts # attach attach failed: -524 ++test_ima # attach attach failed: -524 ++test_local_storage # attach lsm attach failed: -524 ++test_lsm # test_lsm_first_attach unexpected error: -524 (errno 524) ++test_overhead # attach_fentry unexpected error: -524 ++timer # timer unexpected error: -524 (errno 524) ++timer_crash # timer_crash__attach unexpected error: -524 (errno 524) ++timer_mim # timer_mim unexpected error: -524 (errno 524) ++trace_printk # trace_printk__attach unexpected error: -1 (errno 524) ++trace_vprintk # trace_vprintk__attach unexpected error: -1 (errno 524) ++tracing_struct # tracing_struct__attach unexpected error: -524 (errno 524) ++trampoline_count # attach_prog unexpected error: -524 ++unpriv_bpf_disabled # skel_attach unexpected error: -524 (errno 524) ++user_ringbuf/test_user_ringbuf_post_misaligned # misaligned_skel unexpected error: -524 (errno 524) ++user_ringbuf/test_user_ringbuf_post_producer_wrong_offset ++user_ringbuf/test_user_ringbuf_post_larger_than_ringbuf_sz ++user_ringbuf/test_user_ringbuf_basic # ringbuf_basic_skel unexpected error: -524 (errno 524) ++user_ringbuf/test_user_ringbuf_sample_full_ring_buffer ++user_ringbuf/test_user_ringbuf_post_alignment_autoadjust ++user_ringbuf/test_user_ringbuf_overfill ++user_ringbuf/test_user_ringbuf_discards_properly_ignored ++user_ringbuf/test_user_ringbuf_loop ++user_ringbuf/test_user_ringbuf_msg_protocol ++user_ringbuf/test_user_ringbuf_blocking_reserve ++verify_pkcs7_sig # test_verify_pkcs7_sig__attach unexpected error: -524 (errno 524) ++vmlinux # skel_attach skeleton attach failed: -524 +-- +2.30.2 + diff --git a/ci/diffs/0001-selftests-bpf-Panic-on-hard-soft-lockup.patch b/ci/diffs/0001-selftests-bpf-Panic-on-hard-soft-lockup.patch new file mode 100644 index 0000000000000..08f2352bc1992 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Panic-on-hard-soft-lockup.patch @@ -0,0 +1,57 @@ +From 5ed88f81511ce695692f0510ab3ca17eee68eff6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20M=C3=BCller?= +Date: Tue, 25 Oct 2022 23:15:46 +0000 +Subject: [PATCH] selftests/bpf: Panic on hard/soft lockup +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When running tests, we should probably accept any help we can get when +it comes to detecting issues early or making them more debuggable. We +have seen a few cases where a test_progs_noalu32 run, for example, +encountered a soft lockup and stopped making progress. It was only +interrupted once we hit the overall test timeout [0]. We can not and do +not want to necessarily rely on test timeouts, because those rely on +infrastructure provided by the environment we run in (and which is not +present in tools/testing/selftests/bpf/vmtest.sh, for example). +To that end, let's enable panics on soft as well as hard lockups to fail +fast should we encounter one. That's happening in the configuration +indented to be used for selftests (including when using vmtest.sh or +when running in BPF CI). + +[0] https://github.com/kernel-patches/bpf/runs/7844499997 + +Signed-off-by: Daniel Müller +Link: https://lore.kernel.org/r/20221025231546.811766-1-deso@posteo.net +Signed-off-by: Alexei Starovoitov +--- + tools/testing/selftests/bpf/config | 2 ++ + tools/testing/selftests/bpf/config.x86_64 | 1 - + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config +index 921356..7a99a6 100644 +--- a/tools/testing/selftests/bpf/config ++++ b/tools/testing/selftests/bpf/config +@@ -1,4 +1,6 @@ + CONFIG_BLK_DEV_LOOP=y ++CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y ++CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y + CONFIG_BPF=y + CONFIG_BPF_EVENTS=y + CONFIG_BPF_JIT=y +diff --git a/tools/testing/selftests/bpf/config.x86_64 b/tools/testing/selftests/bpf/config.x86_64 +index 21ce5e..dd97d6 100644 +--- a/tools/testing/selftests/bpf/config.x86_64 ++++ b/tools/testing/selftests/bpf/config.x86_64 +@@ -18,7 +18,6 @@ CONFIG_BLK_DEV_RAM=y + CONFIG_BLK_DEV_RAM_SIZE=16384 + CONFIG_BLK_DEV_THROTTLING=y + CONFIG_BONDING=y +-CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y + CONFIG_BOOTTIME_TRACING=y + CONFIG_BPF_JIT_ALWAYS_ON=y + CONFIG_BPF_KPROBE_OVERRIDE=y +-- +2.30.2 + diff --git a/ci/diffs/0001-selftests-bpf-S-iptables-iptables-legacy-in-the-bpf_.patch b/ci/diffs/0001-selftests-bpf-S-iptables-iptables-legacy-in-the-bpf_.patch new file mode 100644 index 0000000000000..e1e5f01a59930 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-S-iptables-iptables-legacy-in-the-bpf_.patch @@ -0,0 +1,77 @@ +From de9c8d848d90cf2e53aced50b350827442ca5a4f Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau +Date: Wed, 12 Oct 2022 15:12:35 -0700 +Subject: [PATCH] selftests/bpf: S/iptables/iptables-legacy/ in the bpf_nf and + xdp_synproxy test + +The recent vm image in CI has reported error in selftests that use +the iptables command. Manu Bretelle has pointed out the difference +in the recent vm image that the iptables is sym-linked to the iptables-nft. +With this knowledge, I can also reproduce the CI error by manually running +with the 'iptables-nft'. + +This patch is to replace the iptables command with iptables-legacy +to unblock the CI tests. + +Signed-off-by: Martin KaFai Lau +Signed-off-by: Andrii Nakryiko +Acked-by: David Vernet +Link: https://lore.kernel.org/bpf/20221012221235.3529719-1-martin.lau@linux.dev +--- + tools/testing/selftests/bpf/prog_tests/bpf_nf.c | 6 +++--- + tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c +index 8a838ea8bdf3..c8ba4009e4ab 100644 +--- a/tools/testing/selftests/bpf/prog_tests/bpf_nf.c ++++ b/tools/testing/selftests/bpf/prog_tests/bpf_nf.c +@@ -49,14 +49,14 @@ static int connect_to_server(int srv_fd) + + static void test_bpf_nf_ct(int mode) + { +- const char *iptables = "iptables -t raw %s PREROUTING -j CONNMARK --set-mark 42/0"; ++ const char *iptables = "iptables-legacy -t raw %s PREROUTING -j CONNMARK --set-mark 42/0"; + int srv_fd = -1, client_fd = -1, srv_client_fd = -1; + struct sockaddr_in peer_addr = {}; + struct test_bpf_nf *skel; + int prog_fd, err; + socklen_t len; + u16 srv_port; +- char cmd[64]; ++ char cmd[128]; + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, + .data_size_in = sizeof(pkt_v4), +@@ -69,7 +69,7 @@ static void test_bpf_nf_ct(int mode) + + /* Enable connection tracking */ + snprintf(cmd, sizeof(cmd), iptables, "-A"); +- if (!ASSERT_OK(system(cmd), "iptables")) ++ if (!ASSERT_OK(system(cmd), cmd)) + goto end; + + srv_port = (mode == TEST_XDP) ? 5005 : 5006; +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c +index 75550a40e029..c72083885b6d 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_synproxy.c +@@ -94,12 +94,12 @@ static void test_synproxy(bool xdp) + SYS("sysctl -w net.ipv4.tcp_syncookies=2"); + SYS("sysctl -w net.ipv4.tcp_timestamps=1"); + SYS("sysctl -w net.netfilter.nf_conntrack_tcp_loose=0"); +- SYS("iptables -t raw -I PREROUTING \ ++ SYS("iptables-legacy -t raw -I PREROUTING \ + -i tmp1 -p tcp -m tcp --syn --dport 8080 -j CT --notrack"); +- SYS("iptables -t filter -A INPUT \ ++ SYS("iptables-legacy -t filter -A INPUT \ + -i tmp1 -p tcp -m tcp --dport 8080 -m state --state INVALID,UNTRACKED \ + -j SYNPROXY --sack-perm --timestamp --wscale 7 --mss 1460"); +- SYS("iptables -t filter -A INPUT \ ++ SYS("iptables-legacy -t filter -A INPUT \ + -i tmp1 -m state --state INVALID -j DROP"); + + ctrl_file = SYS_OUT("./xdp_synproxy --iface tmp1 --ports 8080 \ +-- +2.30.2 + diff --git a/ci/diffs/0001-selftests-bpf-Select-CONFIG_FUNCTION_ERROR_INJECTION.patch b/ci/diffs/0001-selftests-bpf-Select-CONFIG_FUNCTION_ERROR_INJECTION.patch new file mode 100644 index 0000000000000..b4fc1bb37dbdc --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-Select-CONFIG_FUNCTION_ERROR_INJECTION.patch @@ -0,0 +1,45 @@ +From e561fc8365da0215f68cfcffb6c309d1d7eb8c2b Mon Sep 17 00:00:00 2001 +From: Song Liu +Date: Tue, 13 Dec 2022 14:05:00 -0800 +Subject: [PATCH bpf-next] selftests/bpf: Select + CONFIG_FUNCTION_ERROR_INJECTION +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +BPF selftests require CONFIG_FUNCTION_ERROR_INJECTION to work. However, +CONFIG_FUNCTION_ERROR_INJECTION is no longer 'y' by default after recent +changes. As a result, we are seeing errors like the following from BPF CI: + + bpf_testmod_test_read() is not modifiable + __x64_sys_setdomainname is not sleepable + __x64_sys_getpgid is not sleepable + +Fix this by explicitly selecting CONFIG_FUNCTION_ERROR_INJECTION in the +selftest config. + +Fixes: a4412fdd49dc ("error-injection: Add prompt for function error injection") +Reported-by: Daniel Müller +Signed-off-by: Song Liu +Signed-off-by: Andrii Nakryiko +Acked-by: Daniel Müller +Link: https://lore.kernel.org/bpf/20221213220500.3427947-1-song@kernel.org +--- + tools/testing/selftests/bpf/config | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config +index 612f699dc4f7..63cd4ab70171 100644 +--- a/tools/testing/selftests/bpf/config ++++ b/tools/testing/selftests/bpf/config +@@ -16,6 +16,7 @@ CONFIG_CRYPTO_USER_API_HASH=y + CONFIG_DYNAMIC_FTRACE=y + CONFIG_FPROBE=y + CONFIG_FTRACE_SYSCALLS=y ++CONFIG_FUNCTION_ERROR_INJECTION=y + CONFIG_FUNCTION_TRACER=y + CONFIG_GENEVE=y + CONFIG_IKCONFIG=y +-- +2.30.2 + diff --git a/ci/diffs/0001-selftests-bpf-fix-up-Andrii-s-BPF-token-v5-patch-set.patch b/ci/diffs/0001-selftests-bpf-fix-up-Andrii-s-BPF-token-v5-patch-set.patch new file mode 100644 index 0000000000000..00eca06133cf8 --- /dev/null +++ b/ci/diffs/0001-selftests-bpf-fix-up-Andrii-s-BPF-token-v5-patch-set.patch @@ -0,0 +1,32 @@ +From a1f2a6346646c057f1cb5fcf38578159533f85ca Mon Sep 17 00:00:00 2001 +From: Andrii Nakryiko +Date: Tue, 19 Sep 2023 15:18:56 -0700 +Subject: [PATCH] selftests/bpf: fix up Andrii's BPF token v5 patch set + +To avoid unnecessary v6 resubmission just for a potentially +uninitialized err. Let's get some signal from BPF CI. + +Signed-off-by: Andrii Nakryiko +--- + tools/testing/selftests/bpf/prog_tests/token.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/token.c b/tools/testing/selftests/bpf/prog_tests/token.c +index a7b6839d81ac..41cee6b4731e 100644 +--- a/tools/testing/selftests/bpf/prog_tests/token.c ++++ b/tools/testing/selftests/bpf/prog_tests/token.c +@@ -566,8 +566,10 @@ static int userns_prog_load(int mnt_fd) + prog_opts.token_fd = 0; + prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, "token_prog", "GPL", + insns, insn_cnt, &prog_opts); +- if (!ASSERT_EQ(prog_fd, -EPERM, "prog_fd_eperm")) ++ if (!ASSERT_EQ(prog_fd, -EPERM, "prog_fd_eperm")) { ++ err = -EPERM; + goto cleanup; ++ } + + err = drop_priv_caps(&old_caps); + if (!ASSERT_OK(err, "drop_caps")) +-- +2.34.1 + diff --git a/ci/diffs/0001-tracing-fprobe-Initialize-ret-valiable-to-fix-smatch.patch b/ci/diffs/0001-tracing-fprobe-Initialize-ret-valiable-to-fix-smatch.patch new file mode 100644 index 0000000000000..9547c62c40bf9 --- /dev/null +++ b/ci/diffs/0001-tracing-fprobe-Initialize-ret-valiable-to-fix-smatch.patch @@ -0,0 +1,68 @@ +From d3484f640bc82cff459beb85a00f7ebab20f0a41 Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Sun, 9 Apr 2023 11:28:31 +0900 +Subject: [PATCH] tracing: fprobe: Initialize ret valiable to fix smatch error + +The commit 39d954200bf6 ("fprobe: Skip exit_handler if entry_handler returns +!0") introduced a hidden dependency of 'ret' local variable in the +fprobe_handler(), Smatch warns the `ret` can be accessed without +initialization. + + kernel/trace/fprobe.c:59 fprobe_handler() + error: uninitialized symbol 'ret'. + +kernel/trace/fprobe.c + 49 fpr->entry_ip = ip; + 50 if (fp->entry_data_size) + 51 entry_data = fpr->data; + 52 } + 53 + 54 if (fp->entry_handler) + 55 ret = fp->entry_handler(fp, ip, ftrace_get_regs(fregs), entry_data); + +ret is only initialized if there is an ->entry_handler + + 56 + 57 /* If entry_handler returns !0, nmissed is not counted. */ + 58 if (rh) { + +rh is only true if there is an ->exit_handler. Presumably if you have +and ->exit_handler that means you also have a ->entry_handler but Smatch +is not smart enough to figure it out. + +--> 59 if (ret) + ^^^ +Warning here. + + 60 rethook_recycle(rh); + 61 else + 62 rethook_hook(rh, ftrace_get_regs(fregs), true); + 63 } + 64 out: + 65 ftrace_test_recursion_unlock(bit); + 66 } + +Reported-by: Dan Carpenter +Link: https://lore.kernel.org/all/85429a5c-a4b9-499e-b6c0-cbd313291c49@kili.mountain +Fixes: 39d954200bf6 ("fprobe: Skip exit_handler if entry_handler returns !0") +Signed-off-by: Masami Hiramatsu (Google) +--- + kernel/trace/fprobe.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c +index 9abb3905bc8e..293184227394 100644 +--- a/kernel/trace/fprobe.c ++++ b/kernel/trace/fprobe.c +@@ -27,7 +27,7 @@ static void fprobe_handler(unsigned long ip, unsigned long parent_ip, + struct rethook_node *rh = NULL; + struct fprobe *fp; + void *entry_data = NULL; +- int bit, ret; ++ int bit, ret = 0; + + fp = container_of(ops, struct fprobe, ops); + if (fprobe_disabled(fp)) +-- +2.34.1 + diff --git a/ci/diffs/0001-veth-take-into-account-peer-device-for-NETDEV_XDP_AC.patch b/ci/diffs/0001-veth-take-into-account-peer-device-for-NETDEV_XDP_AC.patch new file mode 100644 index 0000000000000..b97dba0accaee --- /dev/null +++ b/ci/diffs/0001-veth-take-into-account-peer-device-for-NETDEV_XDP_AC.patch @@ -0,0 +1,83 @@ +From 8267fc71abb2dc47338570e56dd3473a58313fce Mon Sep 17 00:00:00 2001 +From: Lorenzo Bianconi +Date: Mon, 17 Apr 2023 23:53:22 +0200 +Subject: [PATCH] veth: take into account peer device for + NETDEV_XDP_ACT_NDO_XMIT xdp_features flag + +For veth pairs, NETDEV_XDP_ACT_NDO_XMIT is supported by the current +device if the peer one is running a XDP program or if it has GRO enabled. +Fix the xdp_features flags reporting considering peer device and not +current one for NETDEV_XDP_ACT_NDO_XMIT. + +Fixes: fccca038f300 ("veth: take into account device reconfiguration for xdp_features flag") +Signed-off-by: Lorenzo Bianconi +Link: https://lore.kernel.org/r/4f1ca6f6f6b42ae125bfdb5c7782217c83968b2e.1681767806.git.lorenzo@kernel.org +Signed-off-by: Alexei Starovoitov +--- + drivers/net/veth.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/veth.c b/drivers/net/veth.c +index e1b38fbf1dd9..4b3c6647edc6 100644 +--- a/drivers/net/veth.c ++++ b/drivers/net/veth.c +@@ -1262,11 +1262,12 @@ static void veth_set_xdp_features(struct net_device *dev) + + peer = rtnl_dereference(priv->peer); + if (peer && peer->real_num_tx_queues <= dev->real_num_rx_queues) { ++ struct veth_priv *priv_peer = netdev_priv(peer); + xdp_features_t val = NETDEV_XDP_ACT_BASIC | + NETDEV_XDP_ACT_REDIRECT | + NETDEV_XDP_ACT_RX_SG; + +- if (priv->_xdp_prog || veth_gro_requested(dev)) ++ if (priv_peer->_xdp_prog || veth_gro_requested(peer)) + val |= NETDEV_XDP_ACT_NDO_XMIT | + NETDEV_XDP_ACT_NDO_XMIT_SG; + xdp_set_features_flag(dev, val); +@@ -1504,19 +1505,23 @@ static int veth_set_features(struct net_device *dev, + { + netdev_features_t changed = features ^ dev->features; + struct veth_priv *priv = netdev_priv(dev); ++ struct net_device *peer; + int err; + + if (!(changed & NETIF_F_GRO) || !(dev->flags & IFF_UP) || priv->_xdp_prog) + return 0; + ++ peer = rtnl_dereference(priv->peer); + if (features & NETIF_F_GRO) { + err = veth_napi_enable(dev); + if (err) + return err; + +- xdp_features_set_redirect_target(dev, true); ++ if (peer) ++ xdp_features_set_redirect_target(peer, true); + } else { +- xdp_features_clear_redirect_target(dev); ++ if (peer) ++ xdp_features_clear_redirect_target(peer); + veth_napi_del(dev); + } + return 0; +@@ -1598,13 +1603,13 @@ static int veth_xdp_set(struct net_device *dev, struct bpf_prog *prog, + peer->max_mtu = max_mtu; + } + +- xdp_features_set_redirect_target(dev, true); ++ xdp_features_set_redirect_target(peer, true); + } + + if (old_prog) { + if (!prog) { +- if (!veth_gro_requested(dev)) +- xdp_features_clear_redirect_target(dev); ++ if (peer && !veth_gro_requested(dev)) ++ xdp_features_clear_redirect_target(peer); + + if (dev->flags & IFF_UP) + veth_disable_xdp(dev); +-- +2.34.1 + diff --git a/ci/diffs/0001-x86-vdso-Conditionally-export-__vdso_sgx_enter_enclave.patch b/ci/diffs/0001-x86-vdso-Conditionally-export-__vdso_sgx_enter_enclave.patch new file mode 100644 index 0000000000000..c5f90daa56d3b --- /dev/null +++ b/ci/diffs/0001-x86-vdso-Conditionally-export-__vdso_sgx_enter_enclave.patch @@ -0,0 +1,44 @@ +Recently, ld.lld moved from '--undefined-version' to +'--no-undefined-version' as the default, which breaks building the vDSO +when CONFIG_X86_SGX is not set: + + ld.lld: error: version script assignment of 'LINUX_2.6' to symbol '__vdso_sgx_enter_enclave' failed: symbol not defined + +__vdso_sgx_enter_enclave is only included in the vDSO when +CONFIG_X86_SGX is set. Only export it if it will be present in the final +object, which clears up the error. + +Link: https://github.com/ClangBuiltLinux/linux/issues/1756 +Signed-off-by: Nathan Chancellor +--- + +It would be nice if this could be picked up for an -rc release but I +won't argue otherwise. + +Alternatively, we could add '--undefined-version' to the vDSO ldflags +but this does not seem unreasonable to me. + + arch/x86/entry/vdso/vdso.lds.S | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/x86/entry/vdso/vdso.lds.S b/arch/x86/entry/vdso/vdso.lds.S +index 4bf48462fca7..e8c60ae7a7c8 100644 +--- a/arch/x86/entry/vdso/vdso.lds.S ++++ b/arch/x86/entry/vdso/vdso.lds.S +@@ -27,7 +27,9 @@ VERSION { + __vdso_time; + clock_getres; + __vdso_clock_getres; ++#ifdef CONFIG_X86_SGX + __vdso_sgx_enter_enclave; ++#endif + local: *; + }; + } + +base-commit: f0c4d9fc9cc9462659728d168387191387e903cc + +-- +2.38.1 + + diff --git a/ci/diffs/0002-selftests-bpf-Set-CONFIG_BOOTPARAM_HUNG_TASK_PANIC.patch b/ci/diffs/0002-selftests-bpf-Set-CONFIG_BOOTPARAM_HUNG_TASK_PANIC.patch new file mode 100644 index 0000000000000..2db04e0b9670c --- /dev/null +++ b/ci/diffs/0002-selftests-bpf-Set-CONFIG_BOOTPARAM_HUNG_TASK_PANIC.patch @@ -0,0 +1,39 @@ +From 91c614a38376374ff39c4cc678c2c5cd22cbf8fc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Daniel=20M=C3=BCller?= +Date: Wed, 26 Oct 2022 13:52:28 -0700 +Subject: [PATCH] selftests/bpf: Set CONFIG_BOOTPARAM_HUNG_TASK_PANIC +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +With commit 5ed88f81511ce ("selftests/bpf: Panic on hard/soft lockup") +we enabled the means to panic test runs quickly when they are stuck +because of a hard or soft lockup. What we did not include is the means +to do the same when a hung task is detected. The reasoning there was +that virtualization effects may lead to delays and, hence, spurious +failures. +However, we see the occasional CI timeout when running the test_progs +selftest with internal parallelism enabled (-j) that is not caused by a +hard or soft lockup but due to a hung task. Hence, it makes sense to +enable this detection as well. But let's give it some mileage first +before upstreaming, though, and only include it in BPF CI. + +Signed-off-by: Daniel Müller +--- + tools/testing/selftests/bpf/config | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config +index 7a99a6..6c6821a 100644 +--- a/tools/testing/selftests/bpf/config ++++ b/tools/testing/selftests/bpf/config +@@ -1,5 +1,6 @@ + CONFIG_BLK_DEV_LOOP=y + CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y ++CONFIG_BOOTPARAM_HUNG_TASK_PANIC=y + CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y + CONFIG_BPF=y + CONFIG_BPF_EVENTS=y +-- +2.30.2 + diff --git a/ci/diffs/0002-selftests-bpf-Update-bpf_clone_redirect-expected-ret.patch b/ci/diffs/0002-selftests-bpf-Update-bpf_clone_redirect-expected-ret.patch new file mode 100644 index 0000000000000..2c557e4c6c24d --- /dev/null +++ b/ci/diffs/0002-selftests-bpf-Update-bpf_clone_redirect-expected-ret.patch @@ -0,0 +1,82 @@ +From b772b70b69046c5b76e3f2eda680f692dee5e6d5 Mon Sep 17 00:00:00 2001 +From: Stanislav Fomichev +Date: Mon, 11 Sep 2023 12:47:31 -0700 +Subject: [PATCH 2/2] selftests/bpf: Update bpf_clone_redirect expected return + code + +Commit 151e887d8ff9 ("veth: Fixing transmit return status for dropped +packets") started propagating proper NET_XMIT_DROP error to the caller +which means it's now possible to get positive error code when calling +bpf_clone_redirect() in this particular test. Update the test to reflect +that. + +Reported-by: Daniel Borkmann +Signed-off-by: Stanislav Fomichev +Signed-off-by: Daniel Borkmann +Link: https://lore.kernel.org/bpf/20230911194731.286342-2-sdf@google.com +--- + tools/testing/selftests/bpf/prog_tests/empty_skb.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/bpf/prog_tests/empty_skb.c b/tools/testing/selftests/bpf/prog_tests/empty_skb.c +index 3b77d8a422db..261228eb68e8 100644 +--- a/tools/testing/selftests/bpf/prog_tests/empty_skb.c ++++ b/tools/testing/selftests/bpf/prog_tests/empty_skb.c +@@ -24,6 +24,7 @@ void test_empty_skb(void) + int *ifindex; + int err; + int ret; ++ int lwt_egress_ret; /* expected retval at lwt/egress */ + bool success_on_tc; + } tests[] = { + /* Empty packets are always rejected. */ +@@ -57,6 +58,7 @@ void test_empty_skb(void) + .data_size_in = sizeof(eth_hlen), + .ifindex = &veth_ifindex, + .ret = -ERANGE, ++ .lwt_egress_ret = -ERANGE, + .success_on_tc = true, + }, + { +@@ -70,6 +72,7 @@ void test_empty_skb(void) + .data_size_in = sizeof(eth_hlen), + .ifindex = &ipip_ifindex, + .ret = -ERANGE, ++ .lwt_egress_ret = -ERANGE, + }, + + /* ETH_HLEN+1-sized packet should be redirected. */ +@@ -79,6 +82,7 @@ void test_empty_skb(void) + .data_in = eth_hlen_pp, + .data_size_in = sizeof(eth_hlen_pp), + .ifindex = &veth_ifindex, ++ .lwt_egress_ret = 1, /* veth_xmit NET_XMIT_DROP */ + }, + { + .msg = "ipip ETH_HLEN+1 packet ingress", +@@ -108,8 +112,12 @@ void test_empty_skb(void) + + for (i = 0; i < ARRAY_SIZE(tests); i++) { + bpf_object__for_each_program(prog, bpf_obj->obj) { +- char buf[128]; ++ bool at_egress = strstr(bpf_program__name(prog), "egress") != NULL; + bool at_tc = !strncmp(bpf_program__section_name(prog), "tc", 2); ++ int expected_ret; ++ char buf[128]; ++ ++ expected_ret = at_egress && !at_tc ? tests[i].lwt_egress_ret : tests[i].ret; + + tattr.data_in = tests[i].data_in; + tattr.data_size_in = tests[i].data_size_in; +@@ -128,7 +136,7 @@ void test_empty_skb(void) + if (at_tc && tests[i].success_on_tc) + ASSERT_GE(bpf_obj->bss->ret, 0, buf); + else +- ASSERT_EQ(bpf_obj->bss->ret, tests[i].ret, buf); ++ ASSERT_EQ(bpf_obj->bss->ret, expected_ret, buf); + } + } + +-- +2.34.1 + diff --git a/ci/diffs/0002-tools-headers-uapi-pull-in-stddef.h-to-fix-BPF-selft.patch b/ci/diffs/0002-tools-headers-uapi-pull-in-stddef.h-to-fix-BPF-selft.patch new file mode 100644 index 0000000000000..9070b76442dda --- /dev/null +++ b/ci/diffs/0002-tools-headers-uapi-pull-in-stddef.h-to-fix-BPF-selft.patch @@ -0,0 +1,104 @@ +From 038fafe1d1c92b8488e5e71ebea819050219dd6f Mon Sep 17 00:00:00 2001 +From: Andrii Nakryiko +Date: Wed, 2 Nov 2022 11:04:17 -0700 +Subject: [PATCH 2/2] tools headers uapi: pull in stddef.h to fix BPF selftests + build in CI + +With recent sync of linux/in.h tools/include headers are now relying on +__DECLARE_FLEX_ARRAY macro, which isn't itself defined inside +tools/include headers anywhere and is instead assumed to be present in +system-wide UAPI header. This breaks isolated environments that don't +have kernel UAPI headers installed system-wide, like BPF CI ([0]). + +To fix this, bring in include/uapi/linux/stddef.h into tools/include. We +can't just copy/paste it, though, it has to be processed with +scripts/headers_install.sh, which has a dependency on scripts/unifdef. +So the full command to (re-)generate stddef.h for inclusion into +tools/include directory is: + + $ make scripts_unifdef && \ + cp $KBUILD_OUTPUT/scripts/unifdef scripts/ && \ + scripts/headers_install.sh include/uapi/linux/stddef.h tools/include/uapi/linux/stddef.h + +This assumes KBUILD_OUTPUT envvar is set and used for out-of-tree builds. + + [0] https://github.com/kernel-patches/bpf/actions/runs/3379432493/jobs/5610982609 + +Cc: Jakub Kicinski +Cc: Arnaldo Carvalho de Melo +Fixes: 036b8f5b8970 ("tools headers uapi: Update linux/in.h copy") +Signed-off-by: Andrii Nakryiko +--- + tools/include/uapi/linux/in.h | 1 + + tools/include/uapi/linux/stddef.h | 47 +++++++++++++++++++++++++++++++ + 2 files changed, 48 insertions(+) + create mode 100644 tools/include/uapi/linux/stddef.h + +diff --git a/tools/include/uapi/linux/in.h b/tools/include/uapi/linux/in.h +index f243ce665f74..07a4cb149305 100644 +--- a/tools/include/uapi/linux/in.h ++++ b/tools/include/uapi/linux/in.h +@@ -20,6 +20,7 @@ + #define _UAPI_LINUX_IN_H + + #include ++#include + #include + #include + +diff --git a/tools/include/uapi/linux/stddef.h b/tools/include/uapi/linux/stddef.h +new file mode 100644 +index 000000000000..bb6ea517efb5 +--- /dev/null ++++ b/tools/include/uapi/linux/stddef.h +@@ -0,0 +1,47 @@ ++/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ ++#ifndef _LINUX_STDDEF_H ++#define _LINUX_STDDEF_H ++ ++ ++ ++#ifndef __always_inline ++#define __always_inline __inline__ ++#endif ++ ++/** ++ * __struct_group() - Create a mirrored named and anonyomous struct ++ * ++ * @TAG: The tag name for the named sub-struct (usually empty) ++ * @NAME: The identifier name of the mirrored sub-struct ++ * @ATTRS: Any struct attributes (usually empty) ++ * @MEMBERS: The member declarations for the mirrored structs ++ * ++ * Used to create an anonymous union of two structs with identical layout ++ * and size: one anonymous and one named. The former's members can be used ++ * normally without sub-struct naming, and the latter can be used to ++ * reason about the start, end, and size of the group of struct members. ++ * The named struct can also be explicitly tagged for layer reuse, as well ++ * as both having struct attributes appended. ++ */ ++#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ ++ union { \ ++ struct { MEMBERS } ATTRS; \ ++ struct TAG { MEMBERS } ATTRS NAME; \ ++ } ++ ++/** ++ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union ++ * ++ * @TYPE: The type of each flexible array element ++ * @NAME: The name of the flexible array member ++ * ++ * In order to have a flexible array member in a union or alone in a ++ * struct, it needs to be wrapped in an anonymous struct with at least 1 ++ * named member, but that member can be empty. ++ */ ++#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ ++ struct { \ ++ struct { } __empty_ ## NAME; \ ++ TYPE NAME[]; \ ++ } ++#endif +-- +2.30.2 + diff --git a/ci/vmtest/configs/DENYLIST b/ci/vmtest/configs/DENYLIST new file mode 100644 index 0000000000000..e53b4640180e8 --- /dev/null +++ b/ci/vmtest/configs/DENYLIST @@ -0,0 +1,7 @@ +# TEMPORARY +btf_dump/btf_dump: syntax +kprobe_multi_bench_attach +core_reloc/enum64val +core_reloc/size___diff_sz +core_reloc/type_based___diff_sz +test_ima # All of CI is broken on it following 6.3-rc1 merge diff --git a/ci/vmtest/configs/DENYLIST.aarch64 b/ci/vmtest/configs/DENYLIST.aarch64 new file mode 100644 index 0000000000000..487b19ede4b61 --- /dev/null +++ b/ci/vmtest/configs/DENYLIST.aarch64 @@ -0,0 +1,4 @@ +cgrp_local_storage # libbpf: prog 'update_cookie_tracing': failed to attach: ERROR: strerror_r(-524)=22 +core_reloc_btfgen # run_core_reloc_tests:FAIL:run_btfgen unexpected error: 32512 (errno 22) +usdt/multispec # usdt_300_bad_attach unexpected pointer: 0x558c63d8f0 +xdp_bonding # whole test suite is very unstable on aarch64 diff --git a/ci/vmtest/configs/DENYLIST.s390x b/ci/vmtest/configs/DENYLIST.s390x new file mode 100644 index 0000000000000..e6829c94bdaae --- /dev/null +++ b/ci/vmtest/configs/DENYLIST.s390x @@ -0,0 +1,5 @@ +deny_namespace # not yet in bpf denylist +tc_redirect/tc_redirect_dtime # very flaky +lru_bug # not yet in bpf-next denylist +usdt/basic # failing verifier due to bounds check after LLVM update +usdt/multispec # same as above diff --git a/ci/vmtest/configs/DENYLIST.x86_64 b/ci/vmtest/configs/DENYLIST.x86_64 new file mode 100644 index 0000000000000..6fc3413daab9f --- /dev/null +++ b/ci/vmtest/configs/DENYLIST.x86_64 @@ -0,0 +1 @@ +netcnt # with kvm enabled, fail with packets unexpected packets: actual 10001 != expected 10000 diff --git a/ci/vmtest/configs/run_veristat.kernel.cfg b/ci/vmtest/configs/run_veristat.kernel.cfg new file mode 100644 index 0000000000000..6ac3940672d91 --- /dev/null +++ b/ci/vmtest/configs/run_veristat.kernel.cfg @@ -0,0 +1,3 @@ +VERISTAT_OBJECTS_DIR="/${PROJECT_NAME}/selftests/bpf" +VERISTAT_OBJECTS_GLOB=$(awk '/^#/ { next; } { print $0 ".bpf.o"; }' "${BPF_SELFTESTS_DIR}/veristat.cfg") +VERISTAT_OUTPUT="veristat-kernel" diff --git a/ci/vmtest/configs/run_veristat.meta.cfg b/ci/vmtest/configs/run_veristat.meta.cfg new file mode 100644 index 0000000000000..3b40d25d048fb --- /dev/null +++ b/ci/vmtest/configs/run_veristat.meta.cfg @@ -0,0 +1,3 @@ +VERISTAT_OBJECTS_DIR="/bpf_objects" +VERISTAT_OBJECTS_GLOB="*.o" +VERISTAT_OUTPUT="veristat-meta" diff --git a/ci/vmtest/helpers.sh b/ci/vmtest/helpers.sh new file mode 100755 index 0000000000000..c44d0983156d0 --- /dev/null +++ b/ci/vmtest/helpers.sh @@ -0,0 +1,38 @@ +# shellcheck shell=bash + +# $1 - start or end +# $2 - fold identifier, no spaces +# $3 - fold section description +foldable() { + local YELLOW='\033[1;33m' + local NOCOLOR='\033[0m' + if [ $1 = "start" ]; then + line="::group::$2" + if [ ! -z "${3:-}" ]; then + line="$line - ${YELLOW}$3${NOCOLOR}" + fi + else + line="::endgroup::" + fi + echo -e "$line" +} + +__print() { + local TITLE="" + if [[ -n $2 ]]; then + TITLE=" title=$2" + fi + echo "::$1${TITLE}::$3" +} + +# $1 - title +# $2 - message +print_error() { + __print error $1 $2 +} + +# $1 - title +# $2 - message +print_notice() { + __print notice $1 $2 +} diff --git a/ci/vmtest/run_selftests.sh b/ci/vmtest/run_selftests.sh new file mode 100755 index 0000000000000..8d0f9e02eb2b4 --- /dev/null +++ b/ci/vmtest/run_selftests.sh @@ -0,0 +1,189 @@ +#!/bin/bash + +# run_selftest.sh will run the tests within /${PROJECT_NAME}/selftests/bpf +# If no specific test names are given, all test will be ran, otherwise, it will +# run the test passed as parameters. +# There is 2 ways to pass test names. +# 1) command-line arguments to this script +# 2) a comma-separated list of test names passed as `run_tests` boot parameters. +# test names passed as any of those methods will be ran. + +set -euo pipefail + +source "$(cd "$(dirname "$0")" && pwd)/helpers.sh" + +ARCH=$(uname -m) + +STATUS_FILE=/exitstatus +OUTPUT_DIR=/command_output + +BPF_SELFTESTS_DIR="/${PROJECT_NAME}/selftests/bpf" +VMTEST_CONFIGS_PATH="/${PROJECT_NAME}/vmtest/configs" + +read_lists() { + (for path in "$@"; do + if [[ -s "$path" ]]; then + cat "$path" + fi; + done) | cut -d'#' -f1 | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' | tr -s '\n' ',' +} + +DENYLIST=$(read_lists \ + "$BPF_SELFTESTS_DIR/DENYLIST" \ + "$BPF_SELFTESTS_DIR/DENYLIST.${ARCH}" \ + "$VMTEST_CONFIGS_PATH/DENYLIST" \ + "$VMTEST_CONFIGS_PATH/DENYLIST.${ARCH}" \ +) +ALLOWLIST=$(read_lists \ + "$BPF_SELFTESTS_DIR/ALLOWLIST" \ + "$BPF_SELFTESTS_DIR/ALLOWLIST.${ARCH}" \ + "$VMTEST_CONFIGS_PATH/ALLOWLIST" \ + "$VMTEST_CONFIGS_PATH/ALLOWLIST.${ARCH}" \ +) + +declare -a TEST_NAMES=() + +read_test_names() { + foldable start read_test_names "Reading test names from boot parameters and command line arguments" + # Check if test names were passed as boot parameter. + # We expect `run_tests` to be a comma-separated list of test names. + IFS=',' read -r -a test_names_from_boot <<< \ + "$(sed -n 's/.*run_tests=\([^ ]*\).*/\1/p' /proc/cmdline)" + + echo "${#test_names_from_boot[@]} tests extracted from boot parameters: ${test_names_from_boot[*]}" + # Sort and only keep unique test names from both boot params and arguments + # TEST_NAMES will contain a sorted list of uniq tests to be ran. + # Only do this if any of $test_names_from_boot[@] or $@ has elements as + # "printf '%s\0'" will otherwise generate an empty element. + if [[ ${#test_names_from_boot[@]} -gt 0 || $# -gt 0 ]] + then + readarray -t TEST_NAMES < \ + <(printf '%s\0' "${test_names_from_boot[@]}" "$@" | \ + sort --zero-terminated --unique | \ + xargs --null --max-args=1) + fi + foldable end read_test_names +} + +test_progs_helper() { + local selftest="test_progs${1}" + local args="$2" + + json_file=${selftest/-/_} + if [ "$2" == "-j" ] + then + json_file+="_parallel" + fi + json_file="/${json_file}.json" + + foldable start ${selftest} "Testing ${selftest}" + # "&& true" does not change the return code (it is not executed + # if the Python script fails), but it prevents exiting on a + # failure due to the "set -e". + ./${selftest} ${args} ${DENYLIST:+-d"$DENYLIST"} ${ALLOWLIST:+-a"$ALLOWLIST"} --json-summary "${json_file}" && true + echo "${selftest}:$?" >>"${STATUS_FILE}" + foldable end ${selftest} +} + +test_progs() { + test_progs_helper "" "" +} + +test_progs_parallel() { + test_progs_helper "" "-j" +} + +test_progs_no_alu32() { + test_progs_helper "-no_alu32" "" +} + +test_progs_no_alu32_parallel() { + test_progs_helper "-no_alu32" "-j" +} + +test_maps() { + foldable start test_maps "Testing test_maps" + taskset 0xF ./test_maps && true + echo "test_maps:$?" >>"${STATUS_FILE}" + foldable end test_maps +} + +test_verifier() { + foldable start test_verifier "Testing test_verifier" + ./test_verifier && true + echo "test_verifier:$?" >>"${STATUS_FILE}" + foldable end test_verifier +} + +run_veristat_helper() { + local mode="${1}" + + # Make veristat commands visible in the log + if [ -o xtrace ]; then + xtrace_was_on="1" + else + xtrace_was_on="" + set -x + fi + + ( + # shellcheck source=ci/vmtest/configs/run_veristat.default.cfg + # shellcheck source=ci/vmtest/configs/run_veristat.meta.cfg + source "${VMTEST_CONFIGS_PATH}/run_veristat.${mode}.cfg" + mkdir -p ${OUTPUT_DIR} + pushd "${VERISTAT_OBJECTS_DIR}" + + "${BPF_SELFTESTS_DIR}/veristat" -o csv -q -e file,prog,verdict,states ${VERISTAT_OBJECTS_GLOB} > \ + "${OUTPUT_DIR}/${VERISTAT_OUTPUT}" + + echo "run_veristat_${mode}:$?" >> ${STATUS_FILE} + popd + ) + + # Hide commands again + if [ -z "$xtrace_was_on" ]; then + set +x + fi + +} + +run_veristat_kernel() { + foldable start run_veristat_kernel "Running veristat.kernel" + run_veristat_helper "kernel" + foldable end run_veristat_kernel +} + +run_veristat_meta() { + foldable start run_veristat_meta "Running veristat.meta" + run_veristat_helper "meta" + foldable end run_veristat_meta +} + +foldable end vm_init + +foldable start kernel_config "Kconfig" + +zcat /proc/config.gz + +foldable end kernel_config + +echo "DENYLIST: ${DENYLIST}" +echo "ALLOWLIST: ${ALLOWLIST}" + +cd ${PROJECT_NAME}/selftests/bpf + +# populate TEST_NAMES +read_test_names "$@" +# if we don't have any test name provided to the script, we run all tests. +if [ ${#TEST_NAMES[@]} -eq 0 ]; then + test_progs + test_progs_no_alu32 + test_maps + test_verifier +else + # else we run the tests passed as command-line arguments and through boot + # parameter. + for test_name in "${TEST_NAMES[@]}"; do + "${test_name}" + done +fi