Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions .github/actions/vmtest/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: 'vmtest'
description: 'Build + run vmtest'
inputs:
arch:
description: 'what arch to test'
required: true
default: 'x86_64'
runs:
using: "composite"
steps:
# 1. Setup environment
- name: Setup build environment
uses: libbpf/ci/setup-build-env@master
# 2. Build
- name: Build kernel image
shell: bash
run: ${GITHUB_ACTION_PATH}/build.sh ${{ inputs.arch }}
- name: Build selftests
shell: bash
run: ${GITHUB_ACTION_PATH}/build_selftests.sh
env:
VMLINUX_BTF: ${{ github.workspace }}/vmlinux
# 3. Test
- name: Prepare rootfs
uses: libbpf/ci/prepare-rootfs@master
with:
project-name: 'libbpf'
arch: ${{ inputs.arch }}
kernel-root: '.'
- name: Run selftests
uses: libbpf/ci/run-qemu@master
with:
arch: ${{ inputs.arch}}
img: '/tmp/root.img'
vmlinuz: '${{ github.workspace }}/vmlinuz'
17 changes: 17 additions & 0 deletions .github/actions/vmtest/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

set -euo pipefail

ARCH="$1"

THISDIR="$(cd $(dirname $0) && pwd)"

source "${THISDIR}"/helpers.sh

travis_fold start build_kernel "Building kernel"

cp ${GITHUB_WORKSPACE}/travis-ci/vmtest/configs/config-latest.${ARCH} .config

make -j $((4*$(nproc))) olddefconfig all > /dev/null

travis_fold end build_kernel
42 changes: 42 additions & 0 deletions .github/actions/vmtest/build_selftests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/bin/bash

set -euo pipefail

THISDIR="$(cd $(dirname $0) && pwd)"

source "${THISDIR}"/helpers.sh

travis_fold start prepare_selftests "Building selftests"

LLVM_VER=15
LIBBPF_PATH="${REPO_ROOT}"

PREPARE_SELFTESTS_SCRIPT=${THISDIR}/prepare_selftests-${KERNEL}.sh
if [ -f "${PREPARE_SELFTESTS_SCRIPT}" ]; then
(cd "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" && ${PREPARE_SELFTESTS_SCRIPT})
fi

if [[ "${KERNEL}" = 'LATEST' ]]; then
VMLINUX_H=
else
VMLINUX_H=${THISDIR}/vmlinux.h
fi

cd ${REPO_ROOT}/${REPO_PATH}
make \
CLANG=clang-${LLVM_VER} \
LLC=llc-${LLVM_VER} \
LLVM_STRIP=llvm-strip-${LLVM_VER} \
VMLINUX_BTF="${VMLINUX_BTF}" \
VMLINUX_H="${VMLINUX_H}" \
-C "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
-j $((4*$(nproc))) > /dev/null
cd -
mkdir "${LIBBPF_PATH}"/selftests
cp -R "${REPO_ROOT}/${REPO_PATH}/tools/testing/selftests/bpf" \
"${LIBBPF_PATH}"/selftests
cd "${LIBBPF_PATH}"
rm selftests/bpf/.gitignore
git add selftests

travis_fold end prepare_selftests
44 changes: 44 additions & 0 deletions .github/actions/vmtest/helpers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# $1 - start or end
# $2 - fold identifier, no spaces
# $3 - fold section description
travis_fold() {
local YELLOW='\033[1;33m'
local NOCOLOR='\033[0m'
if [ -z ${GITHUB_WORKFLOW+x} ]; then
echo travis_fold:$1:$2
if [ ! -z "${3:-}" ]; then
echo -e "${YELLOW}$3${NOCOLOR}"
fi
echo
else
if [ $1 = "start" ]; then
line="::group::$2"
if [ ! -z "${3:-}" ]; then
line="$line - ${YELLOW}$3${NOCOLOR}"
fi
else
line="::endgroup::"
fi
echo -e "$line"
fi
}

__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
}
50 changes: 50 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: bpf-ci

on:
pull_request:

concurrency:
group: ci-test-${{ github.head_ref }}
cancel-in-progress: true

jobs:
VM_Test:
runs-on: ${{ matrix.runs_on }}
name: Kernel ${{ matrix.kernel }} on ${{ matrix.runs_on }} + selftests
timeout-minutes: 100
strategy:
fail-fast: false
matrix:
include:
- kernel: 'LATEST'
runs_on: ubuntu-latest
arch: 'x86_64'
- kernel: 'LATEST'
runs_on: z15
arch: 's390x'
env:
AUTHOR_EMAIL: "$(git log -1 --pretty=\"%aE\")"
KERNEL: LATEST
REPO_ROOT: ${{ github.workspace }}
REPO_PATH: ""
steps:
- uses: actions/checkout@v2
- if: ${{ github.repository != 'kernel-patches/bpf' && github.repository != 'kernel-patches/bpf-rc' }}
name: Download bpf-next tree
uses: libbpf/ci/get-linux-source@master
with:
dest: '.kernel'
- if: ${{ github.repository != 'kernel-patches/bpf' && github.repository != 'kernel-patches/bpf-rc' }}
name: Move linux source in place
shell: bash
run: |
rm -rf .kernel/.git
cp -rf .kernel/. .
rm -rf .kernel
- uses: libbpf/ci/patch-kernel@master
with:
patches-root: '${{ github.workspace }}/travis-ci/diffs'
repo-root: '${{ github.workspace }}'
- uses: ./.github/actions/vmtest
with:
arch: ${{ matrix.arch }}
18 changes: 0 additions & 18 deletions README
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 2 additions & 0 deletions include/linux/ftrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ struct dyn_ftrace;
extern int ftrace_direct_func_count;
int register_ftrace_direct(unsigned long ip, unsigned long addr);
int unregister_ftrace_direct(unsigned long ip, unsigned long addr);
int register_ftrace_direct_no_ipmodify(unsigned long ip, unsigned long addr);
int unregister_ftrace_direct_no_ipmodify(unsigned long ip, unsigned long addr);
int modify_ftrace_direct(unsigned long ip, unsigned long old_addr, unsigned long new_addr);
struct ftrace_direct_func *ftrace_find_direct_func(unsigned long addr);
int ftrace_modify_direct_caller(struct ftrace_func_entry *entry,
Expand Down
4 changes: 2 additions & 2 deletions kernel/bpf/trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static int unregister_fentry(struct bpf_trampoline *tr, void *old_addr)
int ret;

if (tr->func.ftrace_managed)
ret = unregister_ftrace_direct((long)ip, (long)old_addr);
ret = unregister_ftrace_direct_no_ipmodify((long)ip, (long)old_addr);
else
ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, old_addr, NULL);

Expand Down Expand Up @@ -159,7 +159,7 @@ static int register_fentry(struct bpf_trampoline *tr, void *new_addr)
return -ENOENT;

if (tr->func.ftrace_managed)
ret = register_ftrace_direct((long)ip, (long)new_addr);
ret = register_ftrace_direct_no_ipmodify((long)ip, (long)new_addr);
else
ret = bpf_arch_text_poke(ip, BPF_MOD_CALL, NULL, new_addr);

Expand Down
74 changes: 67 additions & 7 deletions kernel/trace/ftrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -2467,6 +2467,20 @@ struct ftrace_ops direct_ops = {
*/
.trampoline = FTRACE_REGS_ADDR,
};

struct ftrace_ops no_ipmodify_direct_ops = {
.func = call_direct_funcs,
.flags = FTRACE_OPS_FL_DIRECT | FTRACE_OPS_FL_SAVE_REGS
| FTRACE_OPS_FL_PERMANENT,
/*
* By declaring the main trampoline as this trampoline
* it will never have one allocated for it. Allocated
* trampolines should not call direct functions.
* The direct_ops should only be called by the builtin
* ftrace_regs_caller trampoline.
*/
.trampoline = FTRACE_REGS_ADDR,
};
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */

/**
Expand Down Expand Up @@ -5126,6 +5140,9 @@ static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long addr)
return direct;
}

static int __register_ftrace_direct(unsigned long ip, unsigned long addr,
struct ftrace_ops *ops);

/**
* register_ftrace_direct - Call a custom trampoline directly
* @ip: The address of the nop at the beginning of a function
Expand All @@ -5144,6 +5161,12 @@ static struct ftrace_direct_func *ftrace_alloc_direct_func(unsigned long addr)
* -ENOMEM - There was an allocation failure.
*/
int register_ftrace_direct(unsigned long ip, unsigned long addr)
{
return __register_ftrace_direct(ip, addr, &direct_ops);
}

static int __register_ftrace_direct(unsigned long ip, unsigned long addr,
struct ftrace_ops *ops)
{
struct ftrace_direct_func *direct;
struct ftrace_func_entry *entry;
Expand Down Expand Up @@ -5194,14 +5217,14 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
if (!entry)
goto out_unlock;

ret = ftrace_set_filter_ip(&direct_ops, ip, 0, 0);
ret = ftrace_set_filter_ip(ops, ip, 0, 0);
if (ret)
remove_hash_entry(direct_functions, entry);

if (!ret && !(direct_ops.flags & FTRACE_OPS_FL_ENABLED)) {
ret = register_ftrace_function(&direct_ops);
if (!ret && !(ops->flags & FTRACE_OPS_FL_ENABLED)) {
ret = register_ftrace_function(ops);
if (ret)
ftrace_set_filter_ip(&direct_ops, ip, 1, 0);
ftrace_set_filter_ip(ops, ip, 1, 0);
}

if (ret) {
Expand Down Expand Up @@ -5230,6 +5253,29 @@ int register_ftrace_direct(unsigned long ip, unsigned long addr)
}
EXPORT_SYMBOL_GPL(register_ftrace_direct);

/**
* register_ftrace_direct_no_ipmodify - Call a custom trampoline directly.
* The custom trampoline should not use IP_MODIFY.
* @ip: The address of the nop at the beginning of a function
* @addr: The address of the trampoline to call at @ip
*
* This is used to connect a direct call from the nop location (@ip)
* at the start of ftrace traced functions. The location that it calls
* (@addr) must be able to handle a direct call, and save the parameters
* of the function being traced, and restore them (or inject new ones
* if needed), before returning.
*
* Returns:
* 0 on success
* -EBUSY - Another direct function is already attached (there can be only one)
* -ENODEV - @ip does not point to a ftrace nop location (or not supported)
* -ENOMEM - There was an allocation failure.
*/
int register_ftrace_direct_no_ipmodify(unsigned long ip, unsigned long addr)
{
return __register_ftrace_direct(ip, addr, &no_ipmodify_direct_ops);
}

static struct ftrace_func_entry *find_direct_entry(unsigned long *ip,
struct dyn_ftrace **recp)
{
Expand Down Expand Up @@ -5257,7 +5303,21 @@ static struct ftrace_func_entry *find_direct_entry(unsigned long *ip,
return entry;
}

static int __unregister_ftrace_direct(unsigned long ip, unsigned long addr,
struct ftrace_ops *ops);

int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
{
return __unregister_ftrace_direct(ip, addr, &direct_ops);
}

int unregister_ftrace_direct_no_ipmodify(unsigned long ip, unsigned long addr)
{
return __unregister_ftrace_direct(ip, addr, &no_ipmodify_direct_ops);
}

static int __unregister_ftrace_direct(unsigned long ip, unsigned long addr,
struct ftrace_ops *ops)
{
struct ftrace_direct_func *direct;
struct ftrace_func_entry *entry;
Expand All @@ -5274,11 +5334,11 @@ int unregister_ftrace_direct(unsigned long ip, unsigned long addr)
if (!entry)
goto out_unlock;

hash = direct_ops.func_hash->filter_hash;
hash = ops->func_hash->filter_hash;
if (hash->count == 1)
unregister_ftrace_function(&direct_ops);
unregister_ftrace_function(ops);

ret = ftrace_set_filter_ip(&direct_ops, ip, 1, 0);
ret = ftrace_set_filter_ip(ops, ip, 1, 0);

WARN_ON(ret);

Expand Down
Loading