diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 546a2e207..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,369 +0,0 @@ -# Use the latest 2.1 version of CircleCI pipeline process engine. See: https://circleci.com/docs/2.0/configuration-reference -version: 2.1 - -# prebuilt docker images with toolchain -executors: - setup-rv64gc: - docker: - - image: keystoneenclaveorg/keystone:init-rv64gc - setup-rv32gc: - docker: - - image: keystoneenclaveorg/keystone:init-rv32gc - - -commands: - ###################### - ## General commands ## - ###################### - - update-riscv-toolchain-path-64: - steps: - - run: echo 'export PATH=/keystone/riscv64/bin:$PATH' >> $BASH_ENV - update-riscv-toolchain-path-32: - steps: - - run: echo 'export PATH=/keystone/riscv32/bin:$PATH' >> $BASH_ENV - - ###################### - ## Runtime commands ## - ###################### - - build-sdk: - steps: - - run: | - cd /keystone/sdk - rm -rf build - mkdir build - cd build - KEYSTONE_SDK_DIR=$(pwd) cmake .. - make install - build-runtime: - parameters: - build-name: - type: string - build-dir: - type: string - default: build - build-args: - type: string - default: '' - steps: - - run: - name: << parameters.build-name >> - environment: - KEYSTONE_SDK_DIR: /keystone/sdk/build - command: | - cd runtime - mkdir -p << parameters.build-dir >> - cd << parameters.build-dir >> - cmake -DCMAKE_C_COMPILER=$(which riscv64-unknown-linux-gnu-gcc) \ - -DCMAKE_OBJCOPY=$(which riscv64-unknown-linux-gnu-objcopy) \ - << parameters.build-args >> .. - make - no-output-timeout: 120m - -jobs: - update-dockerhub-image: - parameters: - dockerfile: - type: string - tag: - type: string - docker: - - image: "cimg/base:2022.09" - working_directory: "~/project/keystone" - steps: - - checkout - - setup_remote_docker: - docker_layer_caching: true - - run: - name: "Build and push Docker image (<< parameters.tag >>)" - command: | - cd "docker" - echo "$DOCKER_ACCESS_TOKEN" | \ - docker login -u "$DOCKER_USERNAME" --password-stdin - docker build \ - -t keystoneenclaveorg/keystone:<< parameters.tag >> \ - --build-arg CHECKOUT=master \ - . \ - --platform linux/x86_64 \ - -f << parameters.dockerfile >> - docker push keystoneenclaveorg/keystone:<< parameters.tag >> - - ###################### - ## Full stack tests ## - ###################### - - build-and-test-rv64-qemu: - executor: setup-rv64gc - working_directory: /keystone - steps: - - checkout - - update-riscv-toolchain-path-64 - - run: - name: "Build rv64 and run tests" - command: | - source ./source.sh - ./fast-setup.sh - mkdir build64 - cd build64 - cmake /keystone - make -j$(nproc) - make run-tests - no_output_timeout: 120m - build-rv64-fu540: - executor: setup-rv64gc - working_directory: /keystone - steps: - - checkout - - update-riscv-toolchain-path-64 - - run: - name: "Build rv64 sifive FU540" - command: | - source ./source.sh - ./fast-setup.sh - mkdir build64-fu540 - cd build64-fu540 - cmake /keystone -DLINUX_SIFIVE=y -DSM_PLATFORM=sifive/fu540 - make -j$(nproc) - build-and-test-rv32-qemu: - executor: setup-rv32gc - working_directory: /keystone - steps: - - checkout - - update-riscv-toolchain-path-32 - - run: - name: "Build rv32 and run tests" - command: | - source ./source.sh - BITS=32 ./fast-setup.sh - mkdir build32 - cd build32 - cmake /keystone -DRISCV32=y - make -j$(nproc) - make run-tests - no_output_timeout: 120m - - ################### - ## Runtime tests ## - ################### - - # The format job essentially runs clang-format against the Eyrie codebase. To - # do so, we first query which clang-format git prefers. Then, we run git with - # this clang-format. This ensures that the tool only checks files that have - # been modified. Finally, we check the output of the tool and return an error - # if some formatting changes are necessary. - - format: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - run: apt-get install clang-format -y - - run: - name: "test" - environment: - KEYSTONE_SDK_DIR: /keystone/sdk/build - command: | - FORMAT=$(git help -a | grep clang-format | tail -n1) - FORMAT_RESULT=$(git $FORMAT) - [ "$FORMAT_RESULT" = "no modified files to format" ] || [ "$FORMAT_RESULT" = "clang-format did not modify any files" ] - no_output_timeout: 120m - default-build: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "Default build" - use-freemem: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_FREEMEM" - build-dir: build_freemem - build-args: -DFREEMEM=on - use_linux_syscall_use_freemem: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_LINUX_SYSCALL + USE_FREEMEM" - build-dir: build_syscall_freemem - build-args: -DLINUX_SYSCALL=on -DFREEMEM=on - use_paging: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_PAGING" - build-dir: build_paging - build-args: -DFREEMEM=on -DPAGING=on - use_package_crypto: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_PAGE_CRYPTO" - build-dir: build_paging_crypto - build-args: -DFREEMEM=on -DPAGING=on -DPAGE_CRYPTO=on - use_page_hash: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_PAGE_HASH" - build-dir: build_paging_hash - build-args: -DFREEMEM=on -DPAGING=on -DPAGE_HASH=on - use_page_crypto_use_page_hash: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - build-runtime: - build-name: "USE_PAGE_CRYPTO + USE_PAGE_HASH" - build-dir: build_paging_crypto_hash - build-args: -DFREEMEM=on -DPAGING=on -DPAGE_CRYPTO=on -DPAGE_HASH=on - test: - executor: setup-rv64gc - steps: - - checkout - - update-riscv-toolchain-path-64 - - build-sdk - - run: - name: "test" - environment: - KEYSTONE_SDK_DIR: /keystone/sdk/build - command: | - cd runtime - git submodule sync - git submodule update --init ./test/cmocka - mkdir -p obj/test - pushd obj/test - cmake ../../test - make - ctest -VV || ( cat obj/test/Testing/Temporary/LastTest.log && false ) - popd - no_output_timeout: 120m - -# If the `master` branch is updated, we update the Docker images. As we use -# these images for testing, we have two workflows -- one for the `master` -# branch and one for the all others. -# -# For `master`: -# - Update the Docker images. -# - Once done, run the tests. - -# For all others: -# - Just run the tests. -# -# We accomplish this by filtering by branch, but CircleCI only allows filtering -# by job, so we have repetitions of `only: master` and `ignore: master` for -# `master` and non-`master` branches, respectively. Also note that the `requires` -# key can only refer to jobs in the same workflow. This is why jobs such as -# `use-freemem` need to be duplicated in both workflows. -workflows: - # For the `master` branch only. - update-dockerhub-then-build-and-test: - jobs: - - update-dockerhub-image: - name: update-dockerhub-image-rv64 - dockerfile: Dockerfile.nobuild - tag: init-rv64gc - filters: - branches: - only: master - - update-dockerhub-image: - name: update-dockerhub-image-rv32 - dockerfile: Dockerfile.32.nobuild - tag: init-rv32gc - filters: - branches: - only: master - - update-dockerhub-image: - name: update-dockerhub-image-master - dockerfile: Dockerfile - tag: master - filters: - branches: - only: master - - build-and-test-rv64-qemu: - requires: - - update-dockerhub-image-rv64 - filters: - branches: - only: master - - default-build: - requires: - - update-dockerhub-image-rv64 - filters: - branches: - only: master - - use-freemem: - requires: - - default-build - - use_linux_syscall_use_freemem: - requires: - - default-build - - use_package_crypto: - requires: - - default-build - - use_paging: - requires: - - default-build - - use_page_hash: - requires: - - default-build - - use_page_crypto_use_page_hash: - requires: - - default-build - - test: - requires: - - default-build - # For all other branches. - build-and-test: - jobs: - - build-and-test-rv64-qemu: - filters: - branches: - ignore: master - - default-build: - filters: - branches: - ignore: master - - use-freemem: - requires: - - default-build - - use_linux_syscall_use_freemem: - requires: - - default-build - - use_package_crypto: - requires: - - default-build - - use_paging: - requires: - - default-build - - use_page_hash: - requires: - - default-build - - use_page_crypto_use_page_hash: - requires: - - default-build - - test: - requires: - - default-build - check-code-quality: - jobs: - - format diff --git a/.github/workflows/build-runtime.yml b/.github/workflows/build-runtime.yml new file mode 100644 index 000000000..ef78fc04b --- /dev/null +++ b/.github/workflows/build-runtime.yml @@ -0,0 +1,84 @@ + +on: + workflow_call: + +jobs: + build-runtime: + runs-on: ubuntu-latest + strategy: + matrix: + platform: [generic, unmatched] + bits: [32, 64] + exclude: + # unmatched is not 32 bit + - platform: unmatched + bits: 32 + + steps: + # We don't need submodules here since Keystone is a monorepo! + - name: Checkout Keystone + uses: actions/checkout@v3 + with: + submodules: 'false' + + # Install build dependencies + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y uuid + + - name: Restore build directory + uses: actions/download-artifact@v4 + with: + name: keystone-${{ matrix.platform }}${{ matrix.bits }}-builddir + path: . + + - name: Decompress build directory + run: cat build.tar.xz | xz -d -T0 | tar -xf - + + - name: Build default + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} + + - name: Build USE_ENV_SETUP + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DENV_SETUP=on + + - name: Build USE_LINUX_SYSCALL + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DLINUX_SYSCALL=on + + - name: Build USE_IO_SYSCALL + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DIO_SYSCALL=on + + - name: Build USE_NET_SYSCALL + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DNET_SYSCALL=on + + - name: Build USE_ALL_SYSCALL + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DLINUX_SYSCALL=on -DIO_SYSCALL=on -DNET_SYSCALL=on + + - name: Build USE_PAGING + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DPAGING=on + + - name: Build USE_PAGE_CRYPTO + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DPAGING=on -DPAGE_CRYPTO=on + + - name: Build USE_PAGE_HASH + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DPAGING=on -DPAGE_HASH=on + + - name: Build USE_PAGE_CRYPTO_HASH + run: | + ./scripts/ci/build-runtime.sh $PWD/runtime ${{ matrix.platform }} ${{ matrix.bits }} \ + -DPAGING=on -DPAGE_CRYPTO=on -DPAGE_HASH=on diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..c121f27a0 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,165 @@ +# Run this job on pushes to master and all PRs +name: Build and Test +on: + push: + branches: + - master + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + # Define the strategy for the build job. We generally want to cover each + # platform that we support here + strategy: + matrix: + platform: [generic, unmatched] + bits: [32, 64] + exclude: + # unmatched is not 32 bit + - platform: unmatched + bits: 32 + + steps: + +########### +## Setup ## +########### + + # First, we need to get the version of Keystone we are working on. We + # will also need submodules here since we are doing full builds + - name: Checkout Keystone + uses: actions/checkout@v3 + with: + submodules: 'true' + + # Get various keys for various caches + - name: Get cache keys + id: cache-keys + run: | + # Grab some timestamps for compiler caches + echo "YMDH=$(date -u +'%Y-%m-%d-%H')" >> "$GITHUB_OUTPUT" + echo "YMD=$(date -u +'%Y-%m-%d')" >> "$GITHUB_OUTPUT" + echo "YM=$(date -u +'%Y-%m')" >> "$GITHUB_OUTPUT" + echo "Y=$(date -u +'%Y')" >> "$GITHUB_OUTPUT" + + # Install build dependencies + - name: Install dependencies + run: sudo apt-get update && sudo apt-get install -y cpio rsync bc makeself + + # Restore build and download caches. We key these based on timestamps and build + # target, since these essentially "accumulate" useful information (such as source + # packages or cached compiled objects) over time. With this scheme, we'll pretty + # much always be using the max Github Action cache limit (10GB), but this is okay + # since we really only care about keeping the latest cache anyways. + - name: Restore buildroot packages + uses: actions/cache@v3 + with: + path: buildroot/dl + key: buildroot-dl-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YMDH }} + restore-keys: | + buildroot-dl-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YMD }} + buildroot-dl-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YM }} + buildroot-dl-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.Y }} + buildroot-dl-${{ matrix.platform }}${{ matrix.bits }}- + + - name: Restore ccache + uses: actions/cache@v3 + with: + path: ~/.buildroot-ccache + key: ccache-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YMDH }} + restore-keys: | + ccache-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YMD }} + ccache-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.YM }} + ccache-${{ matrix.platform }}${{ matrix.bits }}-${{ steps.cache-keys.outputs.Y }} + ccache-${{ matrix.platform }}${{ matrix.bits }}- + +############## +## Keystone ## +############## + + # Build Keystone and upload the results log if we fail to do so + - name: Build Keystone + run: | + KEYSTONE_PLATFORM=${{ matrix.platform }} \ + KEYSTONE_BITS=${{ matrix.bits }} make -j$(nproc) + + - name: Upload build log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: build-keystone-${{ matrix.platform }}${{ matrix.bits }}.log + path: build-${{ matrix.platform }}${{ matrix.bits }}/build.log + + # We need parts of the build directory for future tests + - name: Compress build directory + run: | + # Convenient vars + BASEDIR="build-${{ matrix.platform }}${{ matrix.bits }}/buildroot.build" + PERPACKAGEDIR="$BASEDIR/per-package" + + # Needed by most tests + COMPRESSDIRS="$BASEDIR/host $BASEDIR/images" + # Needed by runtime build tests + COMPRESSDIRS="$COMPRESSDIRS $PERPACKAGEDIR/keystone-examples/host/usr/share/keystone/sdk" + # Needed by end-to-end tests + COMPRESSDIRS="$COMPRESSDIRS $BASEDIR/target/root/" + + tar -cf - $COMPRESSDIRS | xz -9 -T0 > build.tar.xz + + - name: Upload build directory + uses: actions/upload-artifact@v4 + with: + name: keystone-${{ matrix.platform }}${{ matrix.bits }}-builddir + path: build.tar.xz + retention-days: 1 + +########### +## Tests ## +########### + + # Generic runtime tests, which only need to run once (on the host) + test-runtime-format: + runs-on: ubuntu-latest + steps: + # We don't need submodules here since Keystone is a monorepo! + - name: Checkout Keystone + uses: actions/checkout@v3 + with: + submodules: 'false' + + - name: Check format + run: | + sudo apt-get update && sudo apt-get install -y clang-format + FORMAT=$(git help -a | grep clang-format | tail -n1) + cd runtime ; FORMAT_RESULT=$(git $FORMAT) + [ "$FORMAT_RESULT" = "no modified files to format" ] || [ "$FORMAT_RESULT" = "clang-format did not modify any files" ] + + test-runtime-functionality: + runs-on: ubuntu-latest + steps: + - name: Checkout Keystone + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Run ctest + run: | + cd runtime + mkdir -p obj/test + pushd obj/test + cmake ../../test + make + ctest -VV || ( cat obj/test/Testing/Temporary/LastTest.log && false ) + popd + + # Build tests, which are run for each supported platform + test-runtime-build: + needs: build + uses: ./.github/workflows/build-runtime.yml + + # System tests, which are run for simulatable platforms + test-system: + needs: build + uses: ./.github/workflows/test-system.yml diff --git a/.github/workflows/test-system.yml b/.github/workflows/test-system.yml new file mode 100644 index 000000000..9af0847dd --- /dev/null +++ b/.github/workflows/test-system.yml @@ -0,0 +1,67 @@ + +on: + workflow_call: + +jobs: + test-system: + runs-on: ubuntu-latest + strategy: + matrix: + platform: [generic] + bits: [32, 64] + + steps: + # We don't need submodules here since Keystone is a monorepo! + - name: Checkout Keystone + uses: actions/checkout@v3 + with: + submodules: 'false' + + - name: Restore build directory + uses: actions/download-artifact@v4 + with: + name: keystone-${{ matrix.platform }}${{ matrix.bits }}-builddir + path: . + + - name: Decompress build directory + run: cat build.tar.xz | xz -d -T0 | tar -xf - + + - name: Test Keystone system + run: | + # Fix permissions on the key + chmod 600 build-${{ matrix.platform }}${{ matrix.bits }}/buildroot.build/target/root/.ssh/id-rsa + + # Launch QEMU + export KEYSTONE_PLATFORM=${{ matrix.platform }} + export KEYSTONE_BITS=${{ matrix.bits }} + export LD_LIBRARY_PATH=build-${{ matrix.platform }}${{ matrix.bits }}/buildroot.build/host/lib + screen -L -dmS qemu bash -c "make run 2>&1 | tee run.log" + + # TODO: check for connectivity instead of sleeping + sleep 20 + + export CALL_LOGFILE=cmd.log + echo "" > $CALL_LOGFILE + + KEYSTONE_COMMAND="modprobe keystone-driver" make call + KEYSTONE_COMMAND="/usr/share/keystone/examples/tests.ke" make call + KEYSTONE_COMMAND="/usr/share/keystone/examples/attestor.ke" make call + KEYSTONE_COMMAND="poweroff" make call + + - name: Check expected + run: | + [[ -z $(diff cmd.log scripts/ci/expected.log) ]] + + - name: Upload run log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-keystone-${{ matrix.platform }}${{ matrix.bits }}-run.log + path: run.log + + - name: Upload cmd log + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-keystone-${{ matrix.platform }}${{ matrix.bits }}-cmd.log + path: cmd.log diff --git a/Makefile b/Makefile index 71a8df1aa..38db144d8 100644 --- a/Makefile +++ b/Makefile @@ -3,8 +3,11 @@ ## Configuration variables ## ############################# -export SHELL := /bin/bash +# Useful globals +export SHELL := /bin/bash +export TERM := xterm-256color +# Keystone configuration export KEYSTONE ?= $(dir $(abspath $(firstword $(MAKEFILE_LIST)))) export KEYSTONE_BUILDROOT ?= $(KEYSTONE)/buildroot export KEYSTONE_BR2_EXT ?= $(KEYSTONE)/overlays @@ -84,7 +87,7 @@ BUILDROOT_TARGET ?= all .PHONY: buildroot buildroot: $(BUILDROOT_BUILDDIR)/.config $(BUILDROOT_OVERLAYDIR)/.done $(call log,info,Building Buildroot) - $(MAKE) $(BUILDROOT_MAKEFLAGS) $(BUILDROOT_TARGET) 2>&1 | \ + set -o pipefail ; $(MAKE) $(BUILDROOT_MAKEFLAGS) $(BUILDROOT_TARGET) 2>&1 | \ tee $(BUILDDIR)/build.log | LC_ALL=C grep -of scripts/grep.patterns # Useful configuration target. This is meant as a development helper to keep diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 9b34d0a2c..6806081fd 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -16,15 +16,7 @@ include(${KEYSTONE_SDK_DIR}/cmake/macros.cmake) include(ExternalProject) find_package(Git REQUIRED) -if(RISCV32) - message(STATUS "riscv32") - set(BITS 32) -else() - message(STATUS "riscv64") - set(BITS 64) -endif() - -use_riscv_toolchain(${BITS}) +use_riscv_toolchain(${KEYSTONE_BITS}) # export include directory include_directories(AFTER ${KEYSTONE_SDK_DIR}/include) diff --git a/examples/attestation/CMakeLists.txt b/examples/attestation/CMakeLists.txt index 7da2c9f03..710c4eca0 100644 --- a/examples/attestation/CMakeLists.txt +++ b/examples/attestation/CMakeLists.txt @@ -4,12 +4,7 @@ set(host_bin attestor-runner) set(host_src host/attestor-runner.cpp host/host.cpp host/verifier.cpp) set(package_name "attestor.ke") set(package_script "./attestor-runner attestor eyrie-rt loader.bin --sm-bin fw_jump.bin") - -if(RISCV32) - set(eyrie_plugins "freemem rv32") -else() - set(eyrie_plugins "freemem") -endif() +set(eyrie_plugins "none") # eapp diff --git a/examples/hello-native/CMakeLists.txt b/examples/hello-native/CMakeLists.txt index 5c88a9709..4740488f3 100644 --- a/examples/hello-native/CMakeLists.txt +++ b/examples/hello-native/CMakeLists.txt @@ -4,12 +4,7 @@ set(host_bin hello-native-runner) set(host_src host/host_native.cpp) set(package_name "hello-native.ke") set(package_script "./hello-native-runner hello-native eyrie-rt loader.bin") - -if(RISCV32) - set(eyrie_plugins "rv32 freemem") -else() - set(eyrie_plugins "freemem") -endif() +set(eyrie_plugins "none") # eapp diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index ff45519c0..ca6485de9 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -4,12 +4,7 @@ set(host_bin hello-runner) set(host_src host/host.cpp) set(package_name "hello.ke") set(package_script "./hello-runner hello eyrie-rt loader.bin") - -if(RISCV32) - set(eyrie_plugins "freemem io_syscall linux_syscall env_setup rv32") -else() - set(eyrie_plugins "freemem io_syscall linux_syscall env_setup") -endif() +set(eyrie_plugins "io_syscall linux_syscall env_setup") # eapp diff --git a/examples/tests/CMakeLists.txt b/examples/tests/CMakeLists.txt index 4117ffa8e..2112642aa 100644 --- a/examples/tests/CMakeLists.txt +++ b/examples/tests/CMakeLists.txt @@ -1,11 +1,6 @@ set(host_bin test-runner) set(host_src test-runner.cpp edge_wrapper.cpp) - -if(RISCV32) - set(eyrie_plugins "freemem rv32") -else() - set(eyrie_plugins "freemem") -endif() +set(eyrie_plugins "none") set(package_name "tests.ke") set(package_script "./run-test.sh") diff --git a/examples/tests/test-runner.cpp b/examples/tests/test-runner.cpp index a98385d70..2a17bbea1 100644 --- a/examples/tests/test-runner.cpp +++ b/examples/tests/test-runner.cpp @@ -134,7 +134,7 @@ main(int argc, char** argv) { asm volatile("rdcycle %0" : "=r"(cycles3)); } - unsigned long encl_ret; + uintptr_t encl_ret; if (!load_only) enclave.run(&encl_ret); if (retval_exist && encl_ret != retval) { diff --git a/mkutils/plat/generic/run.mk b/mkutils/plat/generic/run.mk index 32f15236d..6b02e6f8f 100644 --- a/mkutils/plat/generic/run.mk +++ b/mkutils/plat/generic/run.mk @@ -27,10 +27,18 @@ endif run: $(call log,info,Starting QEMU) - $(BUILDROOT_BUILDDIR)/host/bin/qemu-system-riscv64 $(QEMU_FLAGS) + $(BUILDROOT_BUILDDIR)/host/bin/qemu-system-riscv$(KEYSTONE_BITS) $(QEMU_FLAGS) + +CALL_LOGFILE ?= $(shell mktemp) +call: + $(call log,info,Calling command in QEMU) + ssh -i $(BUILDROOT_BUILDDIR)/target/root/.ssh/id-rsa \ + -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + -p $(QEMU_PORT) root@localhost $(KEYSTONE_COMMAND) 2>&1 | \ + grep -v "Warning: Permanently added" | tee -a $(CALL_LOGFILE) debug-connect: $(call log,info,Connecting to QEMU) - $(BUILDROOT_BUILDDIR)/host/bin/riscv64-buildroot-linux-gnu-gdb \ + $(BUILDROOT_BUILDDIR)/host/bin/riscv$(KEYSTONE_BITS)-buildroot-linux-gnu-gdb \ -iex "set KEYSTONE=$(KEYSTONE)" \ -x $(KEYSTONE)/scripts/gdb/generic.cfg diff --git a/overlays/keystone/configs/linux32-defconfig b/overlays/keystone/configs/linux32-defconfig index 92cd94694..bd68a7fcc 100644 --- a/overlays/keystone/configs/linux32-defconfig +++ b/overlays/keystone/configs/linux32-defconfig @@ -12,9 +12,12 @@ CONFIG_USER_NS=y CONFIG_CHECKPOINT_RESTORE=y CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y +CONFIG_NONPORTABLE=y CONFIG_ARCH_RV32I=y CONFIG_CMODEL_MEDANY=y CONFIG_SMP=y +CONFIG_NR_CPUS=64 +CONFIG_ARCH_MMAP_RND_BITS=17 # CONFIG_GCC_PLUGINS is not set CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y @@ -81,7 +84,11 @@ CONFIG_NFS_V4_2=y CONFIG_ROOT_NFS=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_DEV_VIRTIO=y +# CONFIG_XZ_DEC_IA64 is not set CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=512 CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y +CONFIG_GDB_SCRIPTS=y +CONFIG_FRAME_WARN=2048 # CONFIG_RCU_TRACE is not set diff --git a/overlays/keystone/package/keystone-examples/keystone-examples.mk b/overlays/keystone/package/keystone-examples/keystone-examples.mk index 253f97924..c95c7460b 100644 --- a/overlays/keystone/package/keystone-examples/keystone-examples.mk +++ b/overlays/keystone/package/keystone-examples/keystone-examples.mk @@ -10,9 +10,11 @@ else include $(KEYSTONE)/mkutils/pkg-keystone.mk endif -KEYSTONE_EXAMPLES_DEPENDENCIES += host-keystone-sdk keystone-runtime +KEYSTONE_EXAMPLES_DEPENDENCIES += host-keystone-sdk keystone-runtime opensbi KEYSTONE_EXAMPLES_CONF_OPTS += -DKEYSTONE_SDK_DIR=$(HOST_DIR)/usr/share/keystone/sdk \ - -DKEYSTONE_EYRIE_RUNTIME=$(KEYSTONE_RUNTIME_BUILDDIR) + -DKEYSTONE_EYRIE_RUNTIME=$(KEYSTONE_RUNTIME_BUILDDIR) \ + -DKEYSTONE_BITS=${KEYSTONE_BITS} + KEYSTONE_EXAMPLES_MAKE_ENV += KEYSTONE_SDK_DIR=$(HOST_DIR)/usr/share/keystone/sdk KEYSTONE_EXAMPLES_MAKE_OPTS += examples diff --git a/overlays/keystone/package/keystone-sdk/keystone-sdk.mk b/overlays/keystone/package/keystone-sdk/keystone-sdk.mk index 1fd02f3e0..443db702e 100644 --- a/overlays/keystone/package/keystone-sdk/keystone-sdk.mk +++ b/overlays/keystone/package/keystone-sdk/keystone-sdk.mk @@ -10,7 +10,9 @@ else include $(KEYSTONE)/mkutils/pkg-keystone.mk endif -HOST_KEYSTONE_SDK_CONF_OPTS += -DKEYSTONE_SDK_DIR=$(HOST_DIR)/usr/share/keystone/sdk +HOST_KEYSTONE_SDK_CONF_OPTS += -DKEYSTONE_SDK_DIR=$(HOST_DIR)/usr/share/keystone/sdk \ + -DKEYSTONE_BITS=${KEYSTONE_BITS} + HOST_KEYSTONE_SDK_DEPENDENCIES += toolchain # Clean the examples too if we clean this package diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index f8816d257..f248e919b 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -25,7 +25,6 @@ add_custom_target(options_log COMMAND touch ${CMAKE_BINARY_DIR}/.options_log) # Memory management options -rt_option(FREEMEM "Use freemem allocator" OFF) rt_option(PAGING "Enable runtime paging" OFF) rt_option(PAGE_CRYPTO "Enable page confidentiality" OFF) rt_option(PAGE_HASH "Enable page integrity" OFF) diff --git a/runtime/call/linux_wrap.c b/runtime/call/linux_wrap.c index 92cd0a863..19dc912c7 100644 --- a/runtime/call/linux_wrap.c +++ b/runtime/call/linux_wrap.c @@ -192,7 +192,7 @@ uintptr_t syscall_brk(void* addr){ uintptr_t req_break = (uintptr_t)addr; uintptr_t current_break = get_program_break(); - uintptr_t ret; + uintptr_t ret = -1; int req_page_count = 0; // Return current break if null or current break diff --git a/runtime/call/syscall.c b/runtime/call/syscall.c index eed63fb2b..5a88c1e33 100644 --- a/runtime/call/syscall.c +++ b/runtime/call/syscall.c @@ -157,7 +157,7 @@ void handle_syscall(struct encl_ctx* ctx) uintptr_t arg4 = ctx->regs.a4; // We only use arg5 in these for now, keep warnings happy. -#if defined(USE_LINUX_SYSCALL) || defined(USE_IO_SYSCALL) +#if defined(USE_LINUX_SYSCALL) || defined(USE_NET_SYSCALL) uintptr_t arg5 = ctx->regs.a5; #endif /* IO_SYSCALL */ uintptr_t ret = 0; diff --git a/runtime/include/crypto/merkle.h b/runtime/include/crypto/merkle.h index d35ea2f85..464834955 100644 --- a/runtime/include/crypto/merkle.h +++ b/runtime/include/crypto/merkle.h @@ -1,6 +1,6 @@ #pragma once -#if defined(USE_FREEMEM) && defined(USE_PAGING) +#ifdef USE_PAGING #include #include diff --git a/runtime/include/mm/freemem.h b/runtime/include/mm/freemem.h index deb205e42..30fa1b868 100644 --- a/runtime/include/mm/freemem.h +++ b/runtime/include/mm/freemem.h @@ -1,5 +1,3 @@ -#ifdef USE_FREEMEM - #ifndef __FREEMEM_H__ #define __FREEMEM_H__ @@ -23,4 +21,3 @@ uintptr_t spa_get_zero(void); void spa_put(uintptr_t page); unsigned int spa_available(); #endif -#endif diff --git a/runtime/include/mm/mm.h b/runtime/include/mm/mm.h index ac2b5c42a..c326640d4 100644 --- a/runtime/include/mm/mm.h +++ b/runtime/include/mm/mm.h @@ -7,7 +7,6 @@ uintptr_t translate(uintptr_t va); pte* pte_of_va(uintptr_t va); -#ifdef USE_FREEMEM uintptr_t map_page(uintptr_t vpn, uintptr_t ppn, int flags); uintptr_t alloc_page(uintptr_t vpn, int flags); uintptr_t realloc_page(uintptr_t vpn, int flags); @@ -20,6 +19,5 @@ uintptr_t get_program_break(); void set_program_break(uintptr_t new_break); void map_with_reserved_page_table(uintptr_t base, uintptr_t size, uintptr_t ptr, pte* l2_pt, pte* l3_pt); -#endif /* USE_FREEMEM */ #endif /* _MM_H_ */ diff --git a/runtime/include/mm/paging.h b/runtime/include/mm/paging.h index e83d4580b..263de6e29 100644 --- a/runtime/include/mm/paging.h +++ b/runtime/include/mm/paging.h @@ -1,4 +1,4 @@ -#if defined(USE_FREEMEM) && defined(USE_PAGING) +#ifdef USE_PAGING #ifndef __PAGING_H__ #define __PAGING_H__ diff --git a/runtime/loader-binary/CMakeLists.txt b/runtime/loader-binary/CMakeLists.txt index 2e6ff8971..f54fec8a7 100644 --- a/runtime/loader-binary/CMakeLists.txt +++ b/runtime/loader-binary/CMakeLists.txt @@ -1,6 +1,6 @@ set(LOADER_SOURCES loader.S loader-binary.c) -set(LOADER_LINK_SCRIPT loader.lds) +set(LOADER_LINK_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/loader.lds) add_executable(loader ${LOADER_SOURCES}) target_link_libraries(loader rt_call ld_mm rt_util rt_loader) diff --git a/runtime/loader-binary/loader.lds b/runtime/loader-binary/loader.lds index 622d1692b..a353fe7de 100644 --- a/runtime/loader-binary/loader.lds +++ b/runtime/loader-binary/loader.lds @@ -3,15 +3,19 @@ OUTPUT_ARCH("riscv") ENTRY( _start ) PAGE_SIZE = 0x1000; /* TODO: figure out the page size to use here */ -STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0100; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000; SECTIONS { .text : { PROVIDE( _start = . ); - *(._start); - *(*); + *(._start) + *(.text) + *(.rdata) + *(.rodata) + *(.data) + *(.bss) /* * Only text section is copied into final loader binary diff --git a/runtime/loader/CMakeLists.txt b/runtime/loader/CMakeLists.txt index 59e2c388f..72162f1a6 100644 --- a/runtime/loader/CMakeLists.txt +++ b/runtime/loader/CMakeLists.txt @@ -1,8 +1,3 @@ -set(LOADER_SOURCES elf.c elf32.c elf64.c) - -if(FREEMEM) - list(APPEND LOADER_SOURCES loader.c) -endif() - +set(LOADER_SOURCES elf.c elf32.c elf64.c loader.c) add_library(rt_loader ${LOADER_SOURCES}) diff --git a/runtime/mm/CMakeLists.txt b/runtime/mm/CMakeLists.txt index 3f9550e7a..b4ef6bcbe 100644 --- a/runtime/mm/CMakeLists.txt +++ b/runtime/mm/CMakeLists.txt @@ -1,9 +1,5 @@ -set(MM_SOURCES vm.c page_swap.c) - -if(FREEMEM) - list(APPEND MM_SOURCES mm.c freemem.c) -endif() +set(MM_SOURCES vm.c page_swap.c mm.c freemem.c) if(PAGING) list(APPEND MM_SOURCES paging.c) @@ -13,4 +9,9 @@ add_library(rt_mm ${MM_SOURCES}) set(LD_MM_SOURCES vm.c freemem_ld.c mm.c) add_library(ld_mm ${LD_MM_SOURCES}) -target_compile_options(ld_mm PUBLIC -DLOADER_BIN -DUSE_FREEMEM) +target_compile_options(ld_mm PUBLIC -DLOADER_BIN) + +# Filter out any externally defined use flags +get_target_property(LD_MM_CFLAGS ld_mm COMPILE_OPTIONS) +list(FILTER LD_MM_CFLAGS EXCLUDE REGEX "-DUSE_.*") +set_target_properties(ld_mm PROPERTIES COMPILE_OPTIONS "${LD_MM_CFLAGS}") diff --git a/runtime/mm/freemem.c b/runtime/mm/freemem.c index 9b7337f83..10f06728f 100644 --- a/runtime/mm/freemem.c +++ b/runtime/mm/freemem.c @@ -1,4 +1,3 @@ -#ifdef USE_FREEMEM #include "util/string.h" #include "mm/common.h" #include "mm/vm.h" @@ -110,4 +109,3 @@ spa_init(uintptr_t base, size_t size) spa_put(cur); } } -#endif // USE_FREEMEM diff --git a/runtime/mm/freemem_ld.c b/runtime/mm/freemem_ld.c index 5cf98a809..be0052fe4 100644 --- a/runtime/mm/freemem_ld.c +++ b/runtime/mm/freemem_ld.c @@ -1,4 +1,3 @@ -#ifdef USE_FREEMEM #include "mm/freemem.h" #include "mm/common.h" #include "mm/vm_defs.h" @@ -39,5 +38,3 @@ unsigned int spa_available() { return (freeEnd - freeBase) / RISCV_PAGE_SIZE; } - -#endif diff --git a/runtime/mm/mm.c b/runtime/mm/mm.c index cefe1bef3..280c9c1c0 100644 --- a/runtime/mm/mm.c +++ b/runtime/mm/mm.c @@ -4,8 +4,6 @@ #include "mm/freemem.h" #include "mm/paging.h" -#ifdef USE_FREEMEM - /* Page table utilities */ static pte* __walk_create(pte* root, uintptr_t addr); @@ -49,7 +47,7 @@ __walk_internal(pte* root, uintptr_t addr, int create) t = (pte*) __va(pte_ppn(t[idx]) << RISCV_PAGE_BITS); } - return &t[RISCV_GET_PT_INDEX(addr, 3)]; + return &t[RISCV_GET_PT_INDEX(addr, RISCV_PT_LEVELS)]; } /* walk the page table and return PTE @@ -319,4 +317,3 @@ map_with_reserved_page_table(uintptr_t dram_base, #endif } -#endif /* USE_FREEMEM */ diff --git a/runtime/mm/page_swap.c b/runtime/mm/page_swap.c index 307f84a6a..86504d475 100644 --- a/runtime/mm/page_swap.c +++ b/runtime/mm/page_swap.c @@ -1,6 +1,6 @@ #include "mm/page_swap.h" -#if defined(USE_FREEMEM) && defined(USE_PAGING) +#ifdef USE_PAGING #include #include diff --git a/runtime/mm/paging.c b/runtime/mm/paging.c index a5dfebc4d..e983eac28 100644 --- a/runtime/mm/paging.c +++ b/runtime/mm/paging.c @@ -1,8 +1,4 @@ -#if defined(USE_PAGING) && !defined(USE_FREEMEM) -#error "paging requires freemem" -#endif - -#if defined(USE_FREEMEM) && defined(USE_PAGING) +#ifdef USE_PAGING #include "mm/paging.h" @@ -123,7 +119,7 @@ __traverse_page_table_and_pick_internal( /* extending MSB */ if(level == 3 && (i&0x100)) - vaddr = 0xffffffffffffffffUL; + vaddr = -1; ret = __traverse_page_table_and_pick_internal( level - 1, @@ -290,4 +286,4 @@ paging_backing_region_size(void) { return paging_backing_storage_size; } -#endif //USE_FREEMEM +#endif // USE_PAGING diff --git a/runtime/mm/vm.c b/runtime/mm/vm.c index 589565163..e775ef7ce 100644 --- a/runtime/mm/vm.c +++ b/runtime/mm/vm.c @@ -43,15 +43,12 @@ uintptr_t __pa(uintptr_t va) return (va - EYRIE_LOAD_START) + load_pa_start; } -#ifdef USE_FREEMEM - /* Program break */ uintptr_t program_break; /* freemem */ uintptr_t freemem_va_start; size_t freemem_size; -#endif // USE_FREEMEM /* shared buffer */ uintptr_t shared_buffer; diff --git a/runtime/sys/boot.c b/runtime/sys/boot.c index 20b4020d3..1310e3017 100644 --- a/runtime/sys/boot.c +++ b/runtime/sys/boot.c @@ -24,8 +24,6 @@ size_t utm_size; /* defined in entry.S */ extern void* encl_trap_handler; -#ifdef USE_FREEMEM - int verify_and_load_elf_file(uintptr_t ptr, size_t file_size, bool is_eapp) { int ret = 0; // validate elf @@ -57,28 +55,21 @@ init_freemem() spa_init(freemem_va_start, freemem_size); } -#endif // USE_FREEMEM - /* initialize user stack */ void init_user_stack_and_env(ELF(Ehdr) *hdr) { void* user_sp = (void*) EYRIE_USER_STACK_START; - -#ifdef USE_FREEMEM size_t count; uintptr_t stack_end = EYRIE_USER_STACK_END; size_t stack_count = EYRIE_USER_STACK_SIZE >> RISCV_PAGE_BITS; - // allocated stack pages right below the runtime count = alloc_pages(vpn(stack_end), stack_count, PTE_R | PTE_W | PTE_D | PTE_A | PTE_U); assert(count == stack_count); -#endif // USE_FREEMEM - // setup user stack env/aux user_sp = setup_start(user_sp, hdr); @@ -111,7 +102,6 @@ eyrie_boot(uintptr_t dummy, // $a0 contains the return value from the SBI /* set trap vector */ csr_write(stvec, &encl_trap_handler); -#ifdef USE_FREEMEM freemem_va_start = __va(free_paddr); freemem_size = dram_base + dram_size - free_paddr; @@ -134,7 +124,6 @@ eyrie_boot(uintptr_t dummy, // $a0 contains the return value from the SBI #ifdef USE_PAGING init_paging(user_paddr, free_paddr); #endif /* USE_PAGING */ -#endif /* USE_FREEMEM */ /* initialize user stack */ init_user_stack_and_env((ELF(Ehdr) *) __va(user_paddr)); diff --git a/runtime/test/CMakeLists.txt b/runtime/test/CMakeLists.txt index e71420640..ac16d49b3 100644 --- a/runtime/test/CMakeLists.txt +++ b/runtime/test/CMakeLists.txt @@ -13,10 +13,10 @@ include_directories(../include) add_cmocka_test(test_string SOURCES string.c COMPILE_OPTIONS -I${CMAKE_BINARY_DIR}/cmocka/include LINK_LIBRARIES cmocka) add_cmocka_test(test_merkle SOURCES merkle.c ../crypto/sha256.c - COMPILE_OPTIONS -DUSE_PAGE_HASH -DUSE_PAGING -DUSE_FREEMEM -D__riscv_xlen=64 -I${CMAKE_BINARY_DIR}/cmocka/include -g + COMPILE_OPTIONS -DUSE_PAGE_HASH -DUSE_PAGING -D__riscv_xlen=64 -I${CMAKE_BINARY_DIR}/cmocka/include -g LINK_LIBRARIES cmocka) add_cmocka_test(test_pageswap SOURCES page_swap.c ../crypto/merkle.c ../crypto/sha256.c ../crypto/aes.c - COMPILE_OPTIONS -DUSE_PAGE_HASH -DUSE_PAGE_CRYPTO -DUSE_PAGING -DUSE_FREEMEM -D__riscv_xlen=64 -I${CMAKE_BINARY_DIR}/cmocka/include -g + COMPILE_OPTIONS -DUSE_PAGE_HASH -DUSE_PAGE_CRYPTO -DUSE_PAGING -D__riscv_xlen=64 -I${CMAKE_BINARY_DIR}/cmocka/include -g LINK_LIBRARIES cmocka) diff --git a/runtime/util/printf.c b/runtime/util/printf.c index 42fee9800..eaaf05e56 100644 --- a/runtime/util/printf.c +++ b/runtime/util/printf.c @@ -49,7 +49,9 @@ #define PRINTF_SUPPORT_FLOAT // define this to support long long types (%llu or %p) +#if __riscv_xlen == 64 #define PRINTF_SUPPORT_LONG_LONG +#endif // define this to support the ptrdiff_t type (%t) // ptrdiff_t is normally defined in as long or long long type diff --git a/scripts/ci/build-runtime.sh b/scripts/ci/build-runtime.sh new file mode 100755 index 000000000..5f88cd8ba --- /dev/null +++ b/scripts/ci/build-runtime.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# Arguments: +# 1. Runtime source directory +# 2. Platform (i.e. generic, mpfs, etc) +# 3. Bitness (i.e. 32, 64) +# 4... variable number of args with USE flags + +if [[ "$#" -lt 3 ]]; then + echo "usage: build-runtime.sh [src dir] [platform] [bits] [build args ...]" + exit 1 +fi + +# Parse arguments +KEYSTONE_RUNTIME="$1" ; shift +KEYSTONE_PLATFORM="$1" ; shift +KEYSTONE_BITS="$1" ; shift +BUILD_UUID=$(uuid) + +# Create build directory +mkdir -p "build-runtime-$BUILD_UUID" +cd "build-runtime-$BUILD_UUID" || exit 1 + +# Configure cmake +BUILDDIR="$KEYSTONE_RUNTIME/../build-$KEYSTONE_PLATFORM$KEYSTONE_BITS/buildroot.build" +export PATH="$BUILDDIR/host/bin:$PATH" + +cmake "$@" \ + -DCMAKE_C_COMPILER="$(which riscv$KEYSTONE_BITS-buildroot-linux-gnu-gcc)" \ + -DCMAKE_OBJCOPY="$(which riscv$KEYSTONE_BITS-buildroot-linux-gnu-objcopy)" \ + -DKEYSTONE_SDK_DIR="$BUILDDIR/per-package/keystone-examples/host/usr/share/keystone/sdk" \ + ../runtime + +# Build +make -j$(nproc) diff --git a/scripts/ci/expected.log b/scripts/ci/expected.log new file mode 100644 index 000000000..a4bcaf3b6 --- /dev/null +++ b/scripts/ci/expected.log @@ -0,0 +1,25 @@ + +Verifying archive integrity... MD5 checksums are OK. All good. +Uncompressing Keystone Enclave Package +testing test-stack +testing test-loop +testing test-malloc +testing test-long-nop +testing test-fibonacci +testing test-fib-bench +testing test-attestation +Attestation report SIGNATURE is valid +testing test-untrusted +Enclave said: hello world! +Enclave said: 2nd hello world! +Enclave said value: 13 +Enclave said value: 20 +testing test-data-sealing +Enclave said: Sealing key derivation successful! +Verifying archive integrity... MD5 checksums are OK. All good. +Uncompressing Keystone Enclave Package +Enclave said value: 5000 +Enclave said value: 10000 +Attestation report SIGNATURE is valid +Enclave and SM hashes match with expected. +Returned data in the report match with the nonce sent. diff --git a/scripts/gdb.sh b/scripts/gdb.sh deleted file mode 100755 index 035a3f09a..000000000 --- a/scripts/gdb.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -riscv64-unknown-elf-gdb $1 diff --git a/scripts/gdb/pmp.py b/scripts/gdb/pmp.py index 68673c23f..d41681f44 100644 --- a/scripts/gdb/pmp.py +++ b/scripts/gdb/pmp.py @@ -1,11 +1,19 @@ import gdb NUM_PMP_REGISTERS = 16 -NUM_PMP_CONFIGS = int(NUM_PMP_REGISTERS / 8) + +def cfg_regs(bits): + if bits == 32: + return [f'pmpcfg{i}' for i in range(0, int(NUM_PMP_REGISTERS / 4))] + elif bits == 64: + return [f'pmpcfg{2 * i}' for i in range(0, int(NUM_PMP_REGISTERS / 8))] + else: + return None class PMPClear(gdb.Command): - def __init__(self): + def __init__(self, bits): super(PMPClear, self).__init__("pmp-clear", gdb.COMMAND_NONE) + self.cfg_regs = cfg_regs(bits) def invoke(self, arg, from_tty): # Clear addresses @@ -13,12 +21,20 @@ def invoke(self, arg, from_tty): gdb.execute(f'set $pmpaddr{i} = 0') # Clear configuratoins - for i in range(0, int(NUM_PMP_CONFIGS)): - gdb.execute(f'set $pmpcfg{2 * i} = 0') + for reg in self.cfg_regs: + gdb.execute(f'set ${reg} = 0') class PMPDump(gdb.Command): - def __init__(self): + def __init__(self, bits): super(PMPDump, self).__init__("pmp-dump", gdb.COMMAND_NONE) + self.bits = bits + self.cfg_regs = cfg_regs(bits) + if bits == 32: + self.pmp_per_group = 4 + elif bits == 64: + self.pmp_per_group = 8 + else: + self.pmp_per_group = None def invoke(self, arg, from_tty): f = gdb.selected_frame() @@ -27,11 +43,11 @@ def invoke(self, arg, from_tty): prev_addr = None # Parse configurations first - for i in range(0, int(NUM_PMP_CONFIGS)): - cfg_val = f.read_register(f'pmpcfg{2 * i}') + for i, reg in enumerate(self.cfg_regs): + cfg_val = f.read_register(f'{reg}') # Now parse addresses - for j in range(8): + for j in range(self.pmp_per_group): reg_cfg = (cfg_val >> (8 * j)) & 0xFF r = (reg_cfg & 0b00000001) != 0 w = (reg_cfg & 0b00000010) != 0 @@ -39,7 +55,7 @@ def invoke(self, arg, from_tty): a = (reg_cfg & 0b00011000) >> 3 l = (reg_cfg & 0b10000000) != 0 - reg_addr = f.read_register(f'pmpaddr{8 * i + j}') + reg_addr = f.read_register(f'pmpaddr{self.pmp_per_group * i + j}') if a == 0: # Disabled region, continue type = "disabled" @@ -58,7 +74,7 @@ def invoke(self, arg, from_tty): elif a == 3: # NAPOT region. First, find the leftmost 1 type = "NAPOT" - for k in range(64): + for k in range(self.bits): if (reg_addr >> k) & 0b1 == 0: break @@ -69,11 +85,20 @@ def invoke(self, arg, from_tty): print('error: unknown type!') continue - print(f'PMP reg {8 * i + j} {type}') + print(f'PMP reg {self.pmp_per_group * i + j} {type}') print(f'\tcfg\t{hex(reg_cfg)} {"R" if r else ""}{"W" if w else ""}{"X" if x else ""}{"L" if l else ""}') print(f'\taddr\t{hex(reg_addr)} = {hex(range_bottom)} -> {hex(range_top)}') prev_addr = reg_addr -PMPClear() -PMPDump() +# Figure out whether we are in 32-bit or 64-bit mode +misa = int(gdb.selected_frame().read_register('misa')) +print(hex(misa)) +if misa & (0b11 << 30) == 1 << 30: + PMPClear(32) + PMPDump(32) +elif misa & (0b11 << 62) == 2 << 62: + PMPClear(64) + PMPDump(64) +else: + print('Unsupported MISA size') diff --git a/scripts/run-qemu.sh.in b/scripts/run-qemu.sh.in deleted file mode 100755 index 5d625d109..000000000 --- a/scripts/run-qemu.sh.in +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -export HOST_PORT=@qemu_ssh_port@; - -echo "**** Running QEMU SSH on port ${HOST_PORT} ****"; - -export SMP=1; - -while [ "$1" != "" ]; do - if [ "$1" = "-debug" ]; - then - echo "**** GDB port $((HOST_PORT + 1)) ****"; - DEBUG="-gdb tcp::$((HOST_PORT + 1)) -S -d in_asm -D debug.log"; - fi; - if [ "$1" = "-smp" ]; - then - SMP="$2"; - shift; - fi; - shift; -done; - -@qemu_system@ \ - $DEBUG \ - -m 2G \ - -nographic \ - -machine virt,rom=@bootrom_wrkdir@/bootrom.bin \ - -bios @fw_elf@ \ - -kernel @linux_image@ \ - @extra_qemu_options@ \ - -netdev user,id=net0,net=192.168.100.1/24,dhcpstart=192.168.100.128,hostfwd=tcp::${HOST_PORT}-:22 \ - -device virtio-net-device,netdev=net0 \ - -device virtio-rng-pci \ - -smp $SMP diff --git a/scripts/test-qemu.sh.in b/scripts/test-qemu.sh.in deleted file mode 100755 index 15c34529e..000000000 --- a/scripts/test-qemu.sh.in +++ /dev/null @@ -1,32 +0,0 @@ -#!/bin/bash - -SSH_VERSION_MAJOR=$(ssh -V 2>&1 | sed 's/^OpenSSH_\([0-9]*\).*$/\1/') - -SSH_OPTIONS="-i @overlay_root@/.ssh/id_rsa" -SSH_OPTIONS+=" -o StrictHostKeyChecking=no" -SSH_OPTIONS+=" -o UserKnownHostsFile=/dev/null" - -upload_to_qemu() { - # See "Potentially incompatible changes" section in - # https://www.openssh.com/txt/release-9.0 - SCP_OPTIONS= - if [ $SSH_VERSION_MAJOR -ge 9 ]; then - SCP_OPTIONS+=" -O" - fi - echo "Uploading \"$(basename $1)\" to QEMU ..." - scp ${SSH_OPTIONS} ${SCP_OPTIONS} -P @qemu_ssh_port@ $1 root@localhost:. -} - -run_in_qemu() { - echo "Running \"$1\" in QEMU ..." - ssh ${SSH_OPTIONS} -p @qemu_ssh_port@ root@localhost "$1" -} - -run_in_qemu "modprobe keystone-driver" - -run_in_qemu "/usr/share/keystone/examples/tests.ke" - -upload_to_qemu "@fw_bin@" -run_in_qemu "/usr/share/keystone/examples/attestor.ke" - -run_in_qemu "poweroff" diff --git a/scripts/travis.sh b/scripts/travis.sh deleted file mode 100755 index f7040c893..000000000 --- a/scripts/travis.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -EXPECTED_LOG_DIR=$1 - -# Launch QEMU test -screen -L -dmS qemu ./scripts/run-qemu.sh -# TODO: check for connectivity before starting, instead of sleeping -sleep 20 -./scripts/test-qemu.sh 2>&1 | grep -v "Warning: Permanently added" | tee output.log - -diff output.log $EXPECTED_LOG_DIR/test-qemu.expected.log -if [ $? -eq 0 ] -then - echo "[PASS] output.log matches with the expected output" - exit 0 -else - echo "[FAIL] output.log does not match with the expected output" - exit 1 -fi diff --git a/sdk/CMakeLists.txt b/sdk/CMakeLists.txt index d141040e2..2c4345a1d 100644 --- a/sdk/CMakeLists.txt +++ b/sdk/CMakeLists.txt @@ -6,14 +6,6 @@ include(macros.cmake) # BASIC SETUP #------------------------------------------------------------------------------- -if(RISCV32) - message(STATUS "riscv32") - set(BITS 32) -else() - message(STATUS "riscv64") - set(BITS 64) -endif() - set(prog_name keystone-sdk) set(src_dir ${CMAKE_CURRENT_LIST_DIR}) set(scripts_dir ${src_dir}/scripts) @@ -53,7 +45,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -g) endif() -use_riscv_toolchain(${BITS}) +use_riscv_toolchain(${KEYSTONE_BITS}) ################################################################################ # BUILD PROJECTS ################################################################################ diff --git a/sdk/macros.cmake b/sdk/macros.cmake index 1c7f92ed4..561f2d448 100644 --- a/sdk/macros.cmake +++ b/sdk/macros.cmake @@ -118,7 +118,7 @@ macro(add_eyrie_runtime target_name plugins) # the files are passed via ${ARGN} ExternalProject_Add(eyrie-${target_name} PREFIX ${runtime_prefix} DOWNLOAD_COMMAND rm -rf ${eyrie_src} && cp -ar ${KEYSTONE_EYRIE_RUNTIME} ${eyrie_src} - CMAKE_ARGS "${PLUGIN_FLAGS}" -DEYRIE_SRCDIR=${KEYSTONE_EYRIE_RUNTIME} -DKEYSTONE_SDK_DIR=${KEYSTONE_SDK_DIR} + CMAKE_ARGS "${PLUGIN_FLAGS}" -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS}" -DEYRIE_SRCDIR=${KEYSTONE_EYRIE_RUNTIME} -DKEYSTONE_SDK_DIR=${KEYSTONE_SDK_DIR} BUILD_IN_SOURCE TRUE BUILD_BYPRODUCTS ${eyrie_src}/eyrie-rt ${eyrie_src}/.options_log ${eyrie_src}/loader.bin INSTALL_COMMAND "")