aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README51
-rwxr-xr-xbuild.sh113
-rwxr-xr-xlaunch-qemu.sh251
-rw-r--r--stable-commits12
4 files changed, 427 insertions, 0 deletions
diff --git a/README b/README
new file mode 100644
index 0000000..8a7cf61
--- /dev/null
+++ b/README
@@ -0,0 +1,51 @@
+The repository contains the code to enable the SEV support on AMD Eypc Processor.
+
+Prepare Hypervisor:
+===================
+Follow the below steps to prepare the host OS (hypervisor) for SEV support:
+
+# cd /home/user/
+# git clone https://github.com/AMDESE/AMDSEV.git
+# cd AMDSEV
+# ./build.sh (this should take a while, it will build the linux kernel, qemu and ovmf)
+
+The script is designed to produce a kernel debain packages. Install the new kernel
+image as shown below:
+
+# cd /home/user/AMDSEV/output/kernel/
+# sudo dpkg -i linux-image-*.deb
+
+Reboot the host OS and select the "-sev" image from the grub menu.
+
+On successful boot, verify that /dev/sev1 device is created.
+
+Prepare guest OS
+=================
+Follow the below steps to update your guest image with SEV kernel. The step assumes you
+have a working guest image. In below steps we will boot the guest and update the kernel
+image to use our kernel.
+
+1) Launch a guest (non sev)
+ # cd /home/user/AMDSEV/output/qemu-output
+ # sudo ./launch-qmeu.sh -nosev -hda <your disk image>
+
+NOTE: The launch scripts are setup to use UEFI based guest BIOS image (aka OVMF), it is
+assumed that your hard disk image was installed using UEFI based guest BIOS.
+
+2) Login to the guest and copy the linux-image-*deb created during host prepration.
+
+3) Install the kernel image using "dpkg -i linux-image-*.deb"
+
+4) Shutdown the guest
+
+
+Launching SEV Guest
+===================
+
+To launch SEV enabled guest, use:
+
+# cd /home/user/AMDSEV/output/qemu-output
+# sudo ./launch-qemu.sh -hda <your disk image>
+
+
+NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..6e6ea34
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,113 @@
+#!/bin/bash
+
+. ./stable-commits
+
+BUILD_DIR=`pwd`/src
+OUTPUT_DIR=`pwd`/output
+NUM_OF_CORES=`grep -c ^processor /proc/cpuinfo`
+
+run_cmd()
+{
+ echo "$*"
+
+ $*
+ if [ $? -ne 0 ]; then
+ echo "ERROR: $*"
+ exit 1
+ fi
+}
+
+fetch_kernel()
+{
+ run_cmd "mkdir -p ${BUILD_DIR}/kernel"
+ run_cmd "git clone ${KERNEL_GIT_URL} ${BUILD_DIR}/kernel"
+ cd ${BUILD_DIR}/kernel
+ run_cmd "git branch build ${KERNEL_COMMIT}"
+ run_cmd "git checkout build"
+}
+
+build_kernel()
+{
+ if [ ! -d $BUILD_DIR/kernel ]; then
+ fetch_kernel
+ fi
+ cd $BUILD_DIR/kernel
+ cp /boot/config-$(uname -r) .config
+ sed -ie s/CONFIG_LOCALVERSION.*/CONFIG_LOCALVERSION=\"\"/g .config
+ ./scripts/config --enable CONFIG_AMD_MEM_ENCRYPT
+ ./scripts/config --enable CONFIG_CRYPTO_DEV_CCP
+ ./scripts/config --enable CONFIG_CRYPTO_DEV_SP_PSP
+ ./scripts/config --enable CONFIG_CRYPTO_DEV_PSP_SEV
+ ./scripts/config --disable CONFIG_DEBUG_INFO
+ ./scripts/config --module CRYPTO_DEV_CCP_DD
+ ./scripts/config --disable CONFIG_LOCALVERSION_AUTO
+ yes "" | make olddefconfig
+ run_cmd "make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-sev"
+}
+
+fetch_ovmf()
+{
+ run_cmd "mkdir -p ${BUILD_DIR}/edk2"
+ run_cmd "git clone ${EDK2_GIT_URL} ${BUILD_DIR}/edk2"
+ cd ${BUILD_DIR}/edk2
+}
+
+build_ovmf()
+{
+ if [ ! -d $BUILD_DIR/edk2 ]; then
+ fetch_ovmf
+ fi
+ cd $BUILD_DIR/edk2
+ run_cmd "make -C BaseTools"
+ . ./edksetup.sh
+ run_cmd "nice build --cmd-len=64436 \
+ -DDEBUG_ON_SERIAL_PORT=TRUE \
+ -n $(getconf _NPROCESSORS_ONLN) \
+ -a X64 \
+ -a IA32 \
+ -t GCC5 \
+ -p OvmfPkg/OvmfPkgIa32X64.dsc"
+ run_cmd "mkdir -p $OUTPUT_DIR/qemu-output/share/qemu"
+ run_cmd "cp Build/Ovmf3264/DEBUG_GCC5/FV/OVMF_CODE.fd $OUTPUT_DIR/qemu-output/share/qemu"
+ run_cmd "cp Build/Ovmf3264/DEBUG_GCC5/FV/OVMF_VARS.fd $OUTPUT_DIR/qemu-output/"
+}
+
+fetch_qemu()
+{
+ run_cmd "mkdir -p ${BUILD_DIR}/qemu"
+ run_cmd "git clone ${QEMU_GIT_URL} ${BUILD_DIR}/qemu"
+ cd ${BUILD_DIR}/qemu
+ run_cmd "git branch build ${QEMU_COMMIT}"
+ run_cmd "git checkout build"
+}
+
+build_qemu()
+{
+ if [ ! -d $BUILD_DIR/qemu ]; then
+ fetch_qemu
+ fi
+ cd $BUILD_DIR/qemu
+ run_cmd "./configure --target-list=x86_64-softmmu \
+ --prefix=$OUTPUT_DIR/qemu-output"
+ run_cmd "make -j$(getconf _NPROCESSORS_ONLN)"
+ run_cmd "make -j$(getconf _NPROCESSORS_ONLN) install"
+}
+
+finalize_output()
+{
+ run_cmd "mkdir -p $OUTPUT_DIR/kernel"
+ run_cmd "mv $BUILD_DIR/linux-* $OUTPUT_DIR/kernel"
+ run_cmd "cp $BUILD_DIR/../launch-qemu.sh $OUTPUT_DIR/qemu-output"
+}
+
+dep_install ()
+{
+ # install the build dependencies
+ run_cmd "sudo apt-get -y install git build-essential zlib1g-dev libglib2.0-dev libpixman-1-dev uuid-dev nasm bison acpica-tools libncurses5-dev libssl-dev fakeroot dpkg-dev"
+}
+
+dep_install
+build_kernel
+build_qemu
+build_ovmf
+finalize_output
diff --git a/launch-qemu.sh b/launch-qemu.sh
new file mode 100755
index 0000000..f9baad5
--- /dev/null
+++ b/launch-qemu.sh
@@ -0,0 +1,251 @@
+#!/bin/bash
+
+#
+# user changeable parameters
+#
+HDA_FILE="${HOME}/ubuntu-16.04-desktop.qcow2"
+GUEST_SIZE_IN_MB="2048"
+SEV_GUEST="1"
+SMP_NCPUS="4"
+CONSOLE="serial"
+QEMU_INSTALL_DIR=`pwd`/bin/
+UEFI_BIOS_CODE="`pwd`/share/qemu/OVMF_CODE.fd"
+UEFI_BIOS_VARS="`pwd`/OVMF_VARS.fd"
+#VNC_PORT=""
+AUTOSTART="1"
+
+usage() {
+ echo "$0 [options]"
+ echo "Available <commands>:"
+ echo " -hda hard disk"
+ echo " -nosev disable sev support"
+ echo " -mem guest memory"
+ echo " -smp number of cpus"
+ echo " -console display console to use (serial or graphics)"
+ echo " -vnc VNC port to use"
+ echo " -bios bios to use (default $UEFI_BIOS_CODE)"
+ echo " -netconsole redirect console to tcp port"
+ echo " -kernel kernel to use"
+ echo " -initrd initrd to use"
+ echo " -noauto do not autostart the guest"
+ echo " -cdrom CDROM image"
+ echo " -hugetlb use hugetlbfs"
+ echo " -background background the launch"
+ exit 1
+}
+
+add_opts() {
+ echo -n "$* " >> ${QEMU_CMDLINE}
+}
+
+stop_network() {
+ if [ "$GUEST_TAP_NAME" = "" ]; then
+ return
+ fi
+ run_cmd "ip tuntap del ${GUEST_TAP_NAME} mode tap"
+}
+
+exit_from_int() {
+ stop_network
+
+ rm -rf ${QEMU_CMDLINE}
+ # restore the mapping
+ stty intr ^c
+ exit 1
+}
+
+run_cmd () {
+ $*
+ if [ $? -ne 0 ]; then
+ echo "command $* failed"
+ exit 1
+ fi
+}
+
+setup_hugetlbfs() {
+ HUGETLBFS=`mount | grep hugetlbfs | awk {'print $3'}`
+ if [ "${HUGETLBFS}" = "" ]; then
+ HUGETLBFS="/hugetlbfs"
+ run_cmd "mkdir -p $HUGETLBFS"
+ echo "Mounting $HUGETLBFS..."
+ run_cmd "mount -t hugetlbfs nodev $HUGETLBFS"
+ fi
+ # calculate number of hugepage we need for the guest
+ HPAGES=$((($GUEST_SIZE_IN_MB / 2) + 50))
+ echo -n "Setting hugepage count "
+ echo $HPAGES | sudo tee /proc/sys/vm/nr_hugepages
+
+ add_opts "-mem-path ${HUGETLBFS}"
+}
+
+setup_bridge_network() {
+ # Get last tap device on host
+ TAP_NUM=`ifconfig | grep tap | tail -1 | cut -c4- | cut -f1 -d ' '`
+ if [ "$TAP_NUM" = "" ]; then
+ TAP_NUM="1"
+ fi
+ TAP_NUM=`echo $(( TAP_NUM + 1 ))`
+ GUEST_TAP_NAME="tap${TAP_NUM}"
+ GUEST_MAC_ADDR=$(printf "00:16:3e:%02x:01:01" 0x${TAP_NUM})
+
+ echo "Starting network adapter '${GUEST_TAP_NAME}' MAC=$GUEST_MAC_ADDR"
+ run_cmd "ip tuntap add $GUEST_TAP_NAME mode tap user `whoami`"
+ run_cmd "ip link set $GUEST_TAP_NAME up"
+ run_cmd "ip link set $GUEST_TAP_NAME master br0"
+
+ add_opts "-device e1000,mac=${GUEST_MAC_ADDR},netdev=net0"
+ add_opts "-netdev tap,id=net0,ifname=$GUEST_TAP_NAME,script=no,downscript=no"
+}
+
+trap exit_from_int SIGINT
+
+if [ `id -u` -ne 0 ]; then
+ echo "Must be run as root!"
+ exit 1
+fi
+
+while [[ $1 != "" ]]; do
+ case "$1" in
+ -hda) HDA_FILE="${2}"
+ shift
+ ;;
+ -nosev) SEV_GUEST=""
+ ;;
+ -mem) GUEST_SIZE_IN_MB=${2}
+ shift
+ ;;
+ -console) CONSOLE=${2}
+ shift
+ ;;
+ -smp) SMP_NCPUS=$2
+ shift
+ ;;
+ -vnc) VNC_PORT=$2
+ shift
+ if [ "${VNC_PORT}" = "" ]; then
+ usage
+ fi
+ ;;
+ -bios) UEFI_BIOS_CODE="`readlink -f $2`"
+ shift
+ ;;
+ -netconsole) NETCONSOLE_PORT=$2
+ shift
+ ;;
+ -initrd) INITRD_FILE=$2
+ shift
+ ;;
+ -kernel) KERNEL_FILE=$2
+ shift
+ ;;
+ -cdrom) CDROM_FILE=$2
+ shift
+ ;;
+ -noauto) AUTOSTART="0"
+ ;;
+ -hugetlb) USE_HUGETLBFS="1"
+ ;;
+ *) usage;;
+ esac
+ shift
+done
+
+# we add all the qemu command line options into a file
+QEMU_CMDLINE=/tmp/cmdline.$$
+rm -rf ${QEMU_CMDLINE}
+
+add_opts "${QEMU_INSTALL_DIR}qemu-system-x86_64"
+
+# Basic virtual machine property
+add_opts "-enable-kvm -cpu host"
+
+# add number of VCPUs
+[ ! -z ${SMP_NCPUS} ] && add_opts "-smp ${SMP_NCPUS},maxcpus=64"
+
+# define guest memory
+add_opts "-m ${GUEST_SIZE_IN_MB}M,slots=5,maxmem=30G"
+
+# The OVMF binary, including the non-volatile variable store, appears as a
+# "normal" qemu drive on the host side, and it is exposed to the guest as a
+# persistent flash device.
+add_opts "-drive if=pflash,format=raw,unit=0,file=${UEFI_BIOS_CODE},readonly"
+add_opts "-drive if=pflash,format=raw,unit=1,file=${UEFI_BIOS_VARS}"
+
+# add CDROM if specified
+[ ! -z ${CDROM_FILE} ] && add_opts "-drive file=${CDROM_FILE},media=cdrom,index=0"
+
+# If harddisk file is specified then add the HDD drive
+if [ ! -z ${HDA_FILE} ]; then
+ if [[ ${HDA_FILE} = *"qcow2" ]]; then
+ add_opts "-drive file=${HDA_FILE},format=qcow2"
+ else
+ add_opts "-drive file=${HDA_FILE},format=raw"
+ fi
+fi
+
+# If this is SEV guest then add the encryption device objects to enable SEV
+if [ ! -z ${SEV_GUEST} ]; then
+ add_opts "-object sev-guest,id=sev0"
+ add_opts "-machine memory-encryption=sev0"
+fi
+
+# if we are asked to use hugetlbfs
+[ ! -z ${USE_HUGETLBFS} ] && setup_hugetlbfs
+
+# If we are asked to redirect the serial console to network port
+if [ "${NETCONSOLE_PORT}" != "" ]; then
+ HOST_ADDR="`ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $1}'`"
+ add_opts "-chardev socket,host=$HOST_ADDR,port=$NETCONSOLE_PORT,id=gnc1,server,nowait"
+ add_opts "-device isa-serial,chardev=gnc1"
+ echo "Setting network console $HOST_ADDR:$NETCONSOLE_PORT"
+fi
+
+# if console is serial then disable graphical interface
+if [ "${CONSOLE}" = "serial" ]; then
+ add_opts "-nographic"
+fi
+
+# if -kernel arg is specified then use the kernel provided in command line for boot
+if [ "${KERNEL_FILE}" != "" ]; then
+ add_opts "-kernel $KERNEL_FILE"
+ add_opts "-append \"console=ttyS0 earlyprintk=serial root=/dev/sda2\""
+ [ ! -z ${INITRD_FILE} ] && add_opts "-initrd ${INITRD_FILE}"
+fi
+
+# start vnc server
+[ ! -z ${VNC_PORT} ] && add_opts "-vnc :${VNC_PORT}" && echo "Starting VNC on port ${VNC_PORT}"
+
+# start monitor on pty and named socket 'monitor'
+add_opts "-monitor pty -monitor unix:monitor,server,nowait"
+
+# do we do not need to autostart the guest
+if [ "${AUTOSTART}" = "0" ]; then
+ echo "Disabling autostart"
+ add_opts "-S"
+fi
+
+# check if host has bridge network
+BR0_STATUS="`ifconfig | grep br0`"
+if [ "$BR0_STATUS" != "" ]; then
+ setup_bridge_network
+fi
+
+# log the console output in stdout.log
+QEMU_CONSOLE_LOG=`pwd`/stdout.log
+
+# save the command line args into log file
+cat $QEMU_CMDLINE | tee ${QEMU_CONSOLE_LOG}
+echo | tee -a ${QEMU_CONSOLE_LOG}
+
+# map CTRL-C to CTRL ]
+echo "Mapping CTRL-C to CTRL-]"
+stty intr ^]
+
+echo "Launching VM ..."
+bash ${QEMU_CMDLINE} 2>&1 | tee -a ${QEMU_CONSOLE_LOG}
+
+# restore the mapping
+stty intr ^c
+
+rm -rf ${QEMU_CMDLINE}
+stop_network
diff --git a/stable-commits b/stable-commits
new file mode 100644
index 0000000..95a625d
--- /dev/null
+++ b/stable-commits
@@ -0,0 +1,12 @@
+#
+# stable commit for SEV test builds
+#
+
+KERNEL_GIT_URL=https://github.com/AMDESE/AMDSEV.git
+KERNEL_COMMIT=e4f36d344edfa6ad58a49b0e3f5f67ba8ba7740a # kernel-rfc-3
+
+QEMU_GIT_URL=https://github.com/AMDESE/AMDSEV.git
+QEMU_COMMIT=b6924ec6794d168ac4d4e6eb3e420d11172d1e02 # qemu-rfc-4+
+
+EDK2_GIT_URL=https://github.com/tianocore/edk2.git
+