From 8594401274a853e2c44400d6557b4f7cb0ed120e Mon Sep 17 00:00:00 2001 From: Harika Nittala Date: Mon, 21 Oct 2024 20:06:36 +0000 Subject: [PATCH] Added new SEV CI PR test for SNP host and guest on self-hosted runner Performs SEV cargo tests on the SNP host and SNP guest Signed-off-by: Harika Nittala --- .github/workflows/sev_ci_pr_testing.yaml | 149 +++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 .github/workflows/sev_ci_pr_testing.yaml diff --git a/.github/workflows/sev_ci_pr_testing.yaml b/.github/workflows/sev_ci_pr_testing.yaml new file mode 100644 index 00000000..d9ba14cd --- /dev/null +++ b/.github/workflows/sev_ci_pr_testing.yaml @@ -0,0 +1,149 @@ +name: SEV CI PR test + +on: + pull_request_target: + types: + - reopened + - opened + - edited + workflow_dispatch: + +jobs: + snp_host_tests: + runs-on: self-hosted + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Verify if SNP is enabled on the host + run: | + verify_snp_host() { + if ! sudo dmesg | grep -i "SEV-SNP enabled" 2>&1 >/dev/null; then + echo -e "SEV-SNP not enabled on the host. Please follow these steps to enable:\n\ + $(echo "${AMDSEV_URL}" | sed 's|\.git$||g')/tree/${AMDSEV_DEFAULT_BRANCH}#prepare-host" + return 1 + fi + } + verify_snp_host + + - name: SEV CI PR test on the host + run: | + echo "Event name = ${{ github.event_name }}" + # Give user access to /dev/sev to run cargo tests w/o permission issues + sudo usermod -a -G kvm $USER + sudo setfacl -m g:kvm:rw /dev/sev + + # Fetch and checkout SEV PR on the host + rm -rf ~/sev + git clone https://github.com/virtee/sev.git + cd sev + + # Checkout PR branch + if [ ${{ github.event_name }} == "pull_request_target" ]; then + git fetch origin pull/${{ github.event.pull_request.number }}/head:${{ github.head_ref }} + git switch ${{ github.head_ref }} + fi + + # Install Rust on the host + source "${HOME}/.cargo/env" 2>/dev/null || true + if ! command -v rustc &> /dev/null; then + echo "Installing Rust..." + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -sSf | sh -s -- -y + source "${HOME}/.cargo/env" 2>/dev/null + fi + + # Cargo SEV PR test on the host + cargo test + + snp_guest_tests: + runs-on: self-hosted + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Launch SNP enabled guest + run: | + rm -rf ~/snp.sh + wget https://raw.githubusercontent.com/LakshmiSaiHarika/sev-utils/Fedora-Latest-SNP-kernel-Upstream/tools/snp.sh + chmod +x snp.sh + + # rm -rf ~/snp/launch + ./snp.sh launch-guest + + - name: Verify SNP on the guest via MSR + run: | + ssh_guest_command() { + GUEST_SSH_KEY_PATH="${HOME}/snp/launch/snp-guest-key" + if [ ! -f "${GUEST_SSH_KEY_PATH}" ]; then + echo "SSH key not present, cannot verify guest SNP enabled." + exit 1 + fi + command="$1" + ssh -p 10022 -i "${GUEST_SSH_KEY_PATH}" -o "StrictHostKeyChecking no" -o "PasswordAuthentication=no" -o ConnectTimeout=1 amd@localhost "${command}" + } + + verify_snp_guest_msr(){ + # Install guest rdmsr package dependencies to insert guest msr module + ssh_guest_command "sudo dnf install -y msr-tools > /dev/null 2>&1" > /dev/null 2>&1 + ssh_guest_command "sudo modprobe msr" > /dev/null 2>&1 + local guest_msr_read=$(ssh_guest_command "sudo rdmsr -p 0 0xc0010131") + guest_msr_read=$(echo "${guest_msr_read}" | tr -d '\r' | bc) + + # Map all the sev features in a single associative array for all guest SEV features + declare -A actual_sev_snp_bit_status=( + [SEV]=$(( ( guest_msr_read >> 0) & 1)) + [SEV-ES]=$(( (guest_msr_read >> 1) & 1)) + [SNP]=$(( (guest_msr_read >> 2) & 1)) + ) + + local sev_snp_error="" + for sev_snp_key in "${!actual_sev_snp_bit_status[@]}"; + do + if [[ ${actual_sev_snp_bit_status[$sev_snp_key]} != 1 ]]; then + # Capture the guest SEV/SNP bit value mismatch + sev_snp_error+=$(echo "$sev_snp_key feature is not active on the guest.\n"); + fi + done + + if [[ ! -z "${sev_snp_error}" ]]; then + >&2 echo -e "ERROR: ${sev_snp_error}" + return 1 + fi + } + + verify_snp_guest_msr + + - name: SEV CI PR test on the guest + run: | + ssh_guest_command() { + # SSH guest commands + GUEST_SSH_KEY_PATH="${HOME}/snp/launch/snp-guest-key" + if [ ! -f "${GUEST_SSH_KEY_PATH}" ]; then + echo "SSH key not present, cannot verify guest SNP enabled." + exit 1 + fi + command="$1" + ssh -p 10022 -i "${GUEST_SSH_KEY_PATH}" -o "StrictHostKeyChecking no" -o "PasswordAuthentication=no" -o ConnectTimeout=1 amd@localhost "${command}" + } + + # Install sev dependencies as a root user + ssh_guest_command "sudo su - </dev/null + sudo dnf install -y git gcc + EOF" + + # Clean up and perform PR test on sev library as root user to fix OS permission denied issues + ssh_guest_command "sudo su - <