From e9e4425c84074efb565cdd898ab1e6f62270d3fb Mon Sep 17 00:00:00 2001 From: Kernel Patches Daemon Date: Tue, 25 Jul 2023 17:04:52 -0700 Subject: [PATCH 1/3] adding ci files --- .github/scripts/veristat-compare.py | 202 ++++++++ .github/workflows/lint.yml | 22 + .github/workflows/test.yml | 460 ++++++++++++++++++ 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 ++ ...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 ++ ...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 ++ ...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/helpers.sh | 38 ++ ci/vmtest/run_selftests.sh | 155 ++++++ 31 files changed, 2530 insertions(+), 18 deletions(-) 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-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-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-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 100755 ci/vmtest/helpers.sh create mode 100755 ci/vmtest/run_selftests.sh 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..cd683a0f30431 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,460 @@ +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: + - id: set-matrix-impl + shell: python3 -I {0} + run: | + 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") as f: + f.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 + + 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": "17"}, + #{"kernel": "LATEST", "runs_on": [], "arch": Arch.aarch64.value, "toolchain": "llvm", "llvm-version": "17"}, + {"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 "${{ github.repository_owner }}" != "kernel-patches" or "${{ 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)) + + 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") ] + + 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'] == "${{env.veristat_arch}}" and + x['toolchain'] == "${{env.veristat_toolchain}}") + set_output("veristat_runs_on", veristat_runs_on) + 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 + shell: bash + run: | + if [ ${{ github.event_name }} = 'push' ]; then + branch="${{ github.ref_name }}" + echo "branch=${branch}" >> "${GITHUB_OUTPUT}" + else + branch="${{ github.base_ref }}" + echo "branch=${branch}" >> "${GITHUB_OUTPUT}" + fi + + upstream=$(echo "${branch}" | sed 's@_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}" + ) + )" + + echo "timestamp=$(TZ=utc git show --format='%cd' --no-patch --date=iso-strict-local ${commit})" >> "${GITHUB_OUTPUT}" + echo "commit=${commit}" >> "${GITHUB_OUTPUT}" + echo "Most recent upstream commit is ${commit}" + - 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: | + set -e -u + + # $1 - the SHA-1 to fetch and check out + fetch_and_checkout() { + local 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 kbuild_output="${1}" + echo "Unable to find earlier upstream ref. Discarding KBUILD_OUTPUT contents..." + rm --recursive --force "${kbuild_output}" + mkdir "${kbuild_output}" + false + } + + # $1 - value of KBUILD_OUTPUT + # $2 - current time in ISO 8601 format + restore_source_code_times() { + local kbuild_output="${1}" + local current_time="${2}" + local src_time="$(date --iso-8601=ns --date="${current_time} - 2 minutes")" + local 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 "${kbuild_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 "${{ steps.get-commit-metadata.outputs.commit }}" > "${KBUILD_OUTPUT}/.build-base-sha" + - 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: | + # 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 + + 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. + file_list="$(find . -iname Makefile | xargs) \ + scripts/ \ + tools/testing/selftests/bpf/ \ + tools/include/ \ + tools/bpf/bpftool/"; + fi + # zstd is installed by default in the runner images. + tar -cf - \ + "${KBUILD_OUTPUT}"/.config \ + "${KBUILD_OUTPUT}"/$(KBUILD_OUTPUT="${KBUILD_OUTPUT}" make -s image_name) \ + "${KBUILD_OUTPUT}"/include/config/auto.conf \ + "${KBUILD_OUTPUT}"/include/generated/autoconf.h \ + "${KBUILD_OUTPUT}"/vmlinux \ + ${file_list} \ + --exclude '*.cmd' \ + --exclude '*.d' \ + --exclude '*.h' \ + --exclude '*.output' \ + selftests/bpf/ | zstd -T0 -19 -o vmlinux-${{ matrix.arch }}-${{ matrix.toolchain_full }}.tar.zst + - if: ${{ github.event_name != 'push' }} + name: Remove KBUILD_OUTPUT contents + 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/ + 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' + test: run_veristat + + - name: Run veristat + uses: libbpf/ci/run-qemu@main + timeout-minutes: 10 + with: + arch: x86_64 + img: '/tmp/root.img' + vmlinuz: '${{ github.workspace }}/vmlinuz' + kernel-root: '.' + max-cpu: 8 + kernel-test: run_veristat + output-dir: '${{ github.workspace }}' + + # veristat.csv is produced by run-qemu run_veristat action + - uses: actions/upload-artifact@v3 + with: + name: ${{ env.arch_and_tool }}-veristat-log + if-no-files-found: error + path: '${{ github.workspace }}/veristat.csv' + + # 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: ${{ env.arch_and_tool }}-veristat-baseline + restore-keys: | + ${{ env.arch_and_tool }}-veristat-baseline- + path: '${{ github.workspace }}/veristat-baseline.csv' + + - if: ${{ github.event_name == 'pull_request' }} + name: Show veristat comparison + run: | + cd ${{ github.workspace }} + if [[ ! -f veristat-baseline.csv ]]; then + echo "No veristat-baseline.csv available" + echo "# No veristat-baseline.csv available" >> $GITHUB_STEP_SUMMARY + exit + fi + selftests/bpf/veristat \ + --output-format csv \ + --emit file,prog,verdict,states \ + --compare veristat-baseline.csv veristat.csv > compare.csv + python3 ./.github/scripts/veristat-compare.py compare.csv + + # For push: just put baseline log to cache + - if: ${{ github.event_name == 'push' }} + run: | + mv '${{ github.workspace }}/veristat.csv' \ + '${{ github.workspace }}/veristat-baseline.csv' + + - if: ${{ github.event_name == 'push' }} + uses: actions/cache/save@v3 + with: + key: ${{ env.arch_and_tool }}-veristat-baseline-${{ github.run_id }} + path: '${{ github.workspace }}/veristat-baseline.csv' 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-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-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-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/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..31f13f2dd36ec --- /dev/null +++ b/ci/vmtest/run_selftests.sh @@ -0,0 +1,155 @@ +#!/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 + +declare -a TEST_NAMES=() + +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' ',' +} + +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() { + foldable start run_veristat "Running veristat" + + globs=$(awk '/^#/ { next; } { print $0 ".bpf.o"; }' ./veristat.cfg) + mkdir -p ${OUTPUT_DIR} + ./veristat -o csv -q -e file,prog,verdict,states ${globs} > ${OUTPUT_DIR}/veristat.csv + echo "run_veristat:$?" >> ${STATUS_FILE} + + foldable end run_veristat +} + +foldable end vm_init + +foldable start kernel_config "Kconfig" + +zcat /proc/config.gz + +foldable end kernel_config + +configs_path=${PROJECT_NAME}/selftests/bpf +local_configs_path=${PROJECT_NAME}/vmtest/configs +DENYLIST=$(read_lists \ + "$configs_path/DENYLIST" \ + "$configs_path/DENYLIST.${ARCH}" \ + "$local_configs_path/DENYLIST" \ + "$local_configs_path/DENYLIST.${ARCH}" \ +) +ALLOWLIST=$(read_lists \ + "$configs_path/ALLOWLIST" \ + "$configs_path/ALLOWLIST.${ARCH}" \ + "$local_configs_path/ALLOWLIST" \ + "$local_configs_path/ALLOWLIST.${ARCH}" \ +) + +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 From 544b66293eaec5ad2ddfd09ae5cb18673b902247 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 25 Jul 2023 10:42:05 +0200 Subject: [PATCH 2/3] bpf: Disable preemption in bpf_perf_event_output The nesting protection in bpf_perf_event_output relies on disabled preemption, which is guaranteed for kprobes and tracepoints. However bpf_perf_event_output can be also called from uprobes context through bpf_prog_run_array_sleepable function which disables migration, but keeps preemption enabled. This can cause task to be preempted by another one inside the nesting protection and lead eventually to two tasks using same perf_sample_data buffer and cause crashes like: kernel tried to execute NX-protected page - exploit attempt? (uid: 0) BUG: unable to handle page fault for address: ffffffff82be3eea ... Call Trace: ? __die+0x1f/0x70 ? page_fault_oops+0x176/0x4d0 ? exc_page_fault+0x132/0x230 ? asm_exc_page_fault+0x22/0x30 ? perf_output_sample+0x12b/0x910 ? perf_event_output+0xd0/0x1d0 ? bpf_perf_event_output+0x162/0x1d0 ? bpf_prog_c6271286d9a4c938_krava1+0x76/0x87 ? __uprobe_perf_func+0x12b/0x540 ? uprobe_dispatcher+0x2c4/0x430 ? uprobe_notify_resume+0x2da/0xce0 ? atomic_notifier_call_chain+0x7b/0x110 ? exit_to_user_mode_prepare+0x13e/0x290 ? irqentry_exit_to_user_mode+0x5/0x30 ? asm_exc_int3+0x35/0x40 Fixing this by disabling preemption in bpf_perf_event_output. Cc: stable@vger.kernel.org Fixes: 8c7dcb84e3b7 ("bpf: implement sleepable uprobes by chaining gps") Acked-by: Hou Tao Signed-off-by: Jiri Olsa --- kernel/trace/bpf_trace.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 5f2dcabad202c..14c9a1a548c9b 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -661,8 +661,7 @@ static DEFINE_PER_CPU(int, bpf_trace_nest_level); BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, u64, flags, void *, data, u64, size) { - struct bpf_trace_sample_data *sds = this_cpu_ptr(&bpf_trace_sds); - int nest_level = this_cpu_inc_return(bpf_trace_nest_level); + struct bpf_trace_sample_data *sds; struct perf_raw_record raw = { .frag = { .size = size, @@ -670,7 +669,12 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, }, }; struct perf_sample_data *sd; - int err; + int nest_level, err; + + preempt_disable(); + + sds = this_cpu_ptr(&bpf_trace_sds); + nest_level = this_cpu_inc_return(bpf_trace_nest_level); if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(sds->sds))) { err = -EBUSY; @@ -691,6 +695,7 @@ BPF_CALL_5(bpf_perf_event_output, struct pt_regs *, regs, struct bpf_map *, map, out: this_cpu_dec(bpf_trace_nest_level); + preempt_enable(); return err; } From f4c000db1e4dd15b4939cf1c9e6a4befe1f3b305 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 25 Jul 2023 10:42:06 +0200 Subject: [PATCH 3/3] bpf: Disable preemption in bpf_event_output We received report [1] of kernel crash, which is caused by using nesting protection without disabled preemption. The bpf_event_output can be called by programs executed by bpf_prog_run_array_cg function that disabled migration but keeps preemption enabled. This can cause task to be preempted by another one inside the nesting protection and lead eventually to two tasks using same perf_sample_data buffer and cause crashes like: BUG: kernel NULL pointer dereference, address: 0000000000000001 #PF: supervisor instruction fetch in kernel mode #PF: error_code(0x0010) - not-present page ... ? perf_output_sample+0x12a/0x9a0 ? finish_task_switch.isra.0+0x81/0x280 ? perf_event_output+0x66/0xa0 ? bpf_event_output+0x13a/0x190 ? bpf_event_output_data+0x22/0x40 ? bpf_prog_dfc84bbde731b257_cil_sock4_connect+0x40a/0xacb ? xa_load+0x87/0xe0 ? __cgroup_bpf_run_filter_sock_addr+0xc1/0x1a0 ? release_sock+0x3e/0x90 ? sk_setsockopt+0x1a1/0x12f0 ? udp_pre_connect+0x36/0x50 ? inet_dgram_connect+0x93/0xa0 ? __sys_connect+0xb4/0xe0 ? udp_setsockopt+0x27/0x40 ? __pfx_udp_push_pending_frames+0x10/0x10 ? __sys_setsockopt+0xdf/0x1a0 ? __x64_sys_connect+0xf/0x20 ? do_syscall_64+0x3a/0x90 ? entry_SYSCALL_64_after_hwframe+0x72/0xdc Fixing this by disabling preemption in bpf_event_output. [1] https://github.com/cilium/cilium/issues/26756 Cc: stable@vger.kernel.org Reported-by: Oleg "livelace" Popov Closes: https://github.com/cilium/cilium/issues/26756 Fixes: 2a916f2f546c ("bpf: Use migrate_disable/enable in array macros and cgroup/lirc code.") Acked-by: Hou Tao Signed-off-by: Jiri Olsa --- kernel/trace/bpf_trace.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 14c9a1a548c9b..6826ebf750b05 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -720,7 +720,6 @@ static DEFINE_PER_CPU(struct bpf_trace_sample_data, bpf_misc_sds); u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, void *ctx, u64 ctx_size, bpf_ctx_copy_t ctx_copy) { - int nest_level = this_cpu_inc_return(bpf_event_output_nest_level); struct perf_raw_frag frag = { .copy = ctx_copy, .size = ctx_size, @@ -737,8 +736,13 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, }; struct perf_sample_data *sd; struct pt_regs *regs; + int nest_level; u64 ret; + preempt_disable(); + + nest_level = this_cpu_inc_return(bpf_event_output_nest_level); + if (WARN_ON_ONCE(nest_level > ARRAY_SIZE(bpf_misc_sds.sds))) { ret = -EBUSY; goto out; @@ -753,6 +757,7 @@ u64 bpf_event_output(struct bpf_map *map, u64 flags, void *meta, u64 meta_size, ret = __bpf_perf_event_output(regs, map, flags, sd); out: this_cpu_dec(bpf_event_output_nest_level); + preempt_enable(); return ret; }