Skip to content
Merged
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
24 changes: 24 additions & 0 deletions doc/patch-author-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ Table of contents
- [Exported symbol versioning](#exported-symbol-versioning)
- [System calls](#system-calls)
- [Symbol Namespaces](#symbol-namespaces)
- [Cross Compile](#cross-compile)


Patch analysis
--------------
Expand Down Expand Up @@ -964,3 +966,25 @@ ERROR: modpost: module livepatch-test uses symbol dma_buf_export from namespace
```
To manually import the required namespace, add the MODULE_IMPORT_NS() macro to
the patch source. For example: `MODULE_IMPORT_NS("DMA_BUF")`

Cross Compile
-------------

It is recommended to build the livepatch in the same environment (compiler/library/etc.) as
the target kernel. When the target kernel was cross compiled for a different architecture,
it is recommended to cross compile the livepatch.

There are two options to cross compile a livepatch.

To specify a separate set of cross compilers,
we can set the `CROSS_COMPILE` environment variable. For example, to use `aarch64-gcc` and `aarch64-ld`,
we can run kpatch-build as
```
CROSS_COMPILE=aarch64- kpatch-build ...
```

llvm/clang supports cross compile with the same binaries. To specify a cross compile target, we can
use the TARGET_ARCH environment variable, for example:
```
TARGET_ARCH=aarch64 kpatch-build ...
```
24 changes: 22 additions & 2 deletions kpatch-build/kpatch-build
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ set -o pipefail
BASE="$PWD"
SCRIPTDIR="$(readlink -f "$(dirname "$(type -p "$0")")")"
ARCH="$(uname -m)"
TARGET_ARCH="${TARGET_ARCH:-$ARCH}"
CPUS="$(getconf _NPROCESSORS_ONLN)"
CACHEDIR="${CACHEDIR:-$HOME/.kpatch}"
KERNEL_SRCDIR="$CACHEDIR/src"
Expand Down Expand Up @@ -390,7 +391,7 @@ find_special_section_data() {
check[e]=true # exception_table_entry

# Arch-specific features
case "$ARCH" in
case "$TARGET_ARCH" in
"x86_64")
check[a]=true # alt_instr
kernel_version_gte 5.10.0 && check[s]=true # static_call_site
Expand Down Expand Up @@ -722,6 +723,15 @@ print_supported_distro(){
fi
}

# Used in "make ARCH=xxx" when making the kernel.
# Match "aarch64" to "arm64", while keep everything else the same.
kernel_make_arch() {
if [[ "$1" == "aarch64" ]]; then
echo "arm64"
else
echo "$1"
fi
}

usage() {
echo "usage: $(basename "$0") [options] <patch1 ... patchN>" >&2
Expand Down Expand Up @@ -1299,6 +1309,11 @@ else
MAKEVARS+=("LD=${KPATCH_CC_PREFIX}${LD}")
fi

if [[ "$ARCH" != "$TARGET_ARCH" ]]; then
KARCH=$(kernel_make_arch "$TARGET_ARCH")
MAKEVARS+=("ARCH=$KARCH")
fi


# $TARGETS used as list, no quotes.
# shellcheck disable=SC2086
Expand Down Expand Up @@ -1489,7 +1504,12 @@ fi
cd "$TEMPDIR/output" || die
# $KPATCH_LDFLAGS and result of find used as list, no quotes.
# shellcheck disable=SC2086,SC2046
"$LD" -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
if [[ "$ARCH" != "$TARGET_ARCH" ]]; then
# if cross compiling, use LLD to link
"$LLD" -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
else
"$LD" -r $KPATCH_LDFLAGS -o ../patch/tmp_output.o $(find . -name "*.o") 2>&1 | logger || die
fi

if [[ "$USE_KLP" -eq 1 ]]; then
cp -f "$TEMPDIR"/patch/tmp_output.o "$TEMPDIR"/patch/output.o || die
Expand Down