diff --git a/.github/workflows/kernel-ci.yml b/.github/workflows/kernel-ci.yml new file mode 100644 index 0000000..e385e72 --- /dev/null +++ b/.github/workflows/kernel-ci.yml @@ -0,0 +1,102 @@ +name: Kernel CI + +on: + pull_request: + branches: [krunfw] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: kernel-ci-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + freshness: + name: Check stable kernel version + runs-on: ubuntu-24.04 + steps: + - name: Code checkout + uses: actions/checkout@v7 + + - name: Check pinned kernel + run: scripts/check-kernel-version.sh + + source: + name: Fetch kernel source + needs: freshness + runs-on: ubuntu-24.04 + steps: + - name: Code checkout + uses: actions/checkout@v7 + + - name: Download kernel source + run: | + kernel_version=$(awk '$1 == "KERNEL_VERSION" { print $3; exit }' Makefile) + make "tarballs/${kernel_version}.tar.gz" + + - name: Verify kernel source archive + run: tar tzf tarballs/*.tar.gz >/dev/null + + - name: Upload kernel source + uses: actions/upload-artifact@v7 + with: + name: kernel-source + path: tarballs/*.tar.gz + compression-level: 0 + retention-days: 1 + + build: + name: Build ${{ matrix.name }} + needs: source + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - name: Linux x86_64 + runner: ubuntu-24.04 + packages: "" + make_args: "" + - name: Windows x86_64 + runner: ubuntu-24.04 + packages: "" + make_args: OS=Windows + - name: SEV x86_64 + runner: ubuntu-24.04 + packages: "" + make_args: SEV=1 + - name: TDX x86_64 + runner: ubuntu-24.04 + packages: "" + make_args: TDX=1 + - name: Linux aarch64 + runner: ubuntu-24.04-arm + packages: "" + make_args: "" + - name: Linux riscv64 + runner: ubuntu-24.04 + packages: gcc-riscv64-linux-gnu + make_args: ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- + steps: + - name: Code checkout + uses: actions/checkout@v7 + + - name: Download kernel source + uses: actions/download-artifact@v8 + with: + name: kernel-source + path: tarballs + + - name: Install build dependencies + env: + EXTRA_PACKAGES: ${{ matrix.packages }} + run: | + sudo apt-get update + sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev cpio xz-utils $EXTRA_PACKAGES + + - name: Build kernel configuration + env: + MAKE_ARGS: ${{ matrix.make_args }} + run: make -j"$(nproc)" $MAKE_ARGS kernel.c diff --git a/.github/workflows/kernel-version-monitor.yml b/.github/workflows/kernel-version-monitor.yml new file mode 100644 index 0000000..c0ae390 --- /dev/null +++ b/.github/workflows/kernel-version-monitor.yml @@ -0,0 +1,71 @@ +name: Kernel version monitor + +on: + schedule: + - cron: "17 7 * * *" + workflow_dispatch: + +permissions: + contents: read + issues: write + +jobs: + check: + name: Check stable kernel version + runs-on: ubuntu-24.04 + steps: + - name: Code checkout + uses: actions/checkout@v7 + + - name: Check pinned kernel + id: kernel + shell: bash + run: | + set +e + output=$(scripts/check-kernel-version.sh) + status=$? + set -e + printf '%s\n' "$output" + while IFS='=' read -r key value; do + if [[ $key == "current" || $key == "latest" ]]; then + echo "$key=$value" >> "$GITHUB_OUTPUT" + fi + done <<< "$output" + echo "status=$status" >> "$GITHUB_OUTPUT" + + - name: Open kernel update issue + if: steps.kernel.outputs.status == '1' + env: + GH_TOKEN: ${{ github.token }} + CURRENT_VERSION: ${{ steps.kernel.outputs.current }} + LATEST_VERSION: ${{ steps.kernel.outputs.latest }} + run: | + issue_title="Kernel stable update available" + issue_number=$(gh api "repos/${GITHUB_REPOSITORY}/issues?state=open&per_page=100" --jq ".[] | select((has(\"pull_request\") | not) and .title == \"$issue_title\") | .number" | head -n 1) + if [[ -n $issue_number ]]; then + echo "Issue #$issue_number already tracks the available update" + exit 0 + fi + printf -v issue_body 'libkrunfw pins Linux %s, but Linux %s is now available in the same stable series. Update `KERNEL_VERSION`, apply every common and TEE patch, and let Kernel CI build all six configurations before merging.\n\nDetected by [this scheduled run](%s/%s/actions/runs/%s).' "$CURRENT_VERSION" "$LATEST_VERSION" "$GITHUB_SERVER_URL" "$GITHUB_REPOSITORY" "$GITHUB_RUN_ID" + gh issue create \ + --title "$issue_title" \ + --body "$issue_body" + + - name: Close resolved kernel update issue + if: steps.kernel.outputs.status == '0' + env: + GH_TOKEN: ${{ github.token }} + run: | + issue_title="Kernel stable update available" + issue_number=$(gh api "repos/${GITHUB_REPOSITORY}/issues?state=open&per_page=100" --jq ".[] | select((has(\"pull_request\") | not) and .title == \"$issue_title\") | .number" | head -n 1) + if [[ -n $issue_number ]]; then + gh issue close "$issue_number" --comment "The pinned kernel now matches the latest stable release in its series." + fi + + - name: Fail when the kernel check did not pass + if: steps.kernel.outputs.status != '0' + env: + CHECK_STATUS: ${{ steps.kernel.outputs.status }} + run: | + echo "Kernel version check failed with status $CHECK_STATUS" >&2 + exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fd62865..9f3907b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Code checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev + run: sudo apt-get update && sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev cpio xz-utils - name: Extract version from Makefile id: version @@ -30,7 +30,7 @@ jobs: run: make -j"$(nproc)" - name: Upload kernel.c as job artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: kernel-c-x86_64 path: kernel.c @@ -50,10 +50,10 @@ jobs: runs-on: ubuntu-24.04-arm steps: - name: Code checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Install dependencies - run: sudo apt-get update && sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev + run: sudo apt-get update && sudo apt-get install -y make gcc bc bison flex elfutils python3-pyelftools curl patch libelf-dev cpio xz-utils - name: Extract version from Makefile id: version @@ -65,7 +65,7 @@ jobs: run: make -j"$(nproc)" - name: Upload kernel.c as job artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: kernel-c-aarch64 path: kernel.c @@ -89,7 +89,7 @@ jobs: needs: build-linux-aarch64 steps: - name: Code checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Extract version from Makefile id: version @@ -98,7 +98,7 @@ jobs: echo "full=$(grep '^FULL_VERSION' Makefile | awk '{print $3}')" >> "$GITHUB_OUTPUT" - name: Download kernel.c artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: kernel-c-aarch64 @@ -120,7 +120,7 @@ jobs: needs: build-linux-x86_64 steps: - name: Code checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Extract version from Makefile id: version @@ -129,7 +129,7 @@ jobs: echo "full=$(grep '^FULL_VERSION' Makefile | awk '{print $3}')" >> "$GITHUB_OUTPUT" - name: Download kernel.c artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: kernel-c-x86_64 @@ -154,7 +154,7 @@ jobs: needs: build-linux-x86_64 steps: - name: Code checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Configure MSVC uses: ilammy/msvc-dev-cmd@v1 @@ -169,7 +169,7 @@ jobs: echo "full=$(grep '^FULL_VERSION' Makefile | awk '{print $3}')" >> "$GITHUB_OUTPUT" - name: Download kernel.c artifact - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: kernel-c-x86_64 diff --git a/Makefile b/Makefile index fe9bdf5..b2b39d9 100644 --- a/Makefile +++ b/Makefile @@ -135,7 +135,7 @@ $(KERNEL_TARBALL): $(KERNEL_SOURCES): $(KERNEL_TARBALL) tar xf $(KERNEL_TARBALL) - for patch in $(KERNEL_PATCHES); do patch -p1 -d $(KERNEL_SOURCES) < "$$patch"; done + ./scripts/apply-kernel-patches.sh $(KERNEL_SOURCES) $(KERNEL_PATCHES) cp config-libkrunfw$(VARIANT)_$(GUESTARCH) $(KERNEL_SOURCES)/.config cd $(KERNEL_SOURCES) ; $(MAKE) olddefconfig diff --git a/scripts/apply-kernel-patches.sh b/scripts/apply-kernel-patches.sh new file mode 100755 index 0000000..08ba4a2 --- /dev/null +++ b/scripts/apply-kernel-patches.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +set -euo pipefail + +if (( $# < 2 )); then + echo "Usage: $0 SOURCE_DIR PATCH..." >&2 + exit 2 +fi + +source_dir=$1 +shift + +for patch_file in "$@"; do + # Force non-interactive behavior so a rejected or reversed patch fails the build immediately. + patch -f -p1 -d "$source_dir" < "$patch_file" +done diff --git a/scripts/check-kernel-version.sh b/scripts/check-kernel-version.sh new file mode 100755 index 0000000..5f3f2fe --- /dev/null +++ b/scripts/check-kernel-version.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +set -euo pipefail + +makefile=${1:-Makefile} +stable_repo=${KERNEL_STABLE_REPO:-https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git} + +current=$(awk '$1 == "KERNEL_VERSION" && $2 == "=" { sub(/^linux-/, "", $3); print $3; exit }' "$makefile") +if [[ ! $current =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "Could not read a stable kernel version from $makefile" >&2 + exit 2 +fi + +series=${current%.*} +if ! tags=$(git ls-remote --refs --tags "$stable_repo" "v${series}.*"); then + echo "Could not query stable kernel tags from $stable_repo" >&2 + exit 2 +fi + +# Ignore release candidates and non-stable suffixes, then compare patch numbers numerically. +latest=$(awk -v series="$series" ' + { + tag = $2 + sub(/^refs\/tags\/v/, "", tag) + count = split(tag, part, ".") + if (count == 3 && part[1] "." part[2] == series && part[3] ~ /^[0-9]+$/) { + patch = part[3] + 0 + if (!found || patch > newest) { + newest = patch + found = 1 + } + } + } + END { + if (found) { + printf "%s.%d\n", series, newest + } + } +' <<< "$tags") + +if [[ -z $latest ]]; then + echo "No stable v${series}.y tags were found in $stable_repo" >&2 + exit 2 +fi + +echo "current=$current" +echo "latest=$latest" + +if [[ $current != "$latest" ]]; then + echo "Kernel $current is not the latest ${series}.y release; update to $latest" >&2 + exit 1 +fi