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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@ src/tarfs/**/modules.order
src/tarfs/**/Module.symvers
src/tarfs-cvm/
tools/osbuilder/root_hash.txt
tools/osbuilder/igvm.log
tools/osbuilder/kata-opa.service
tools/osbuilder/rootfs-builder/opa/

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/overlay/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
all:
cargo build --release

clean:
cargo clean
35 changes: 13 additions & 22 deletions src/runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ GENERATED_VARS = \
CONFIG_QEMU_TDX_IN \
CONFIG_QEMU_SNP_IN \
CONFIG_CLH_IN \
CONFIG_FC_IN \
CONFIG_CLH_SNP_IN \
CONFIG_FC_IN \
CONFIG_STRATOVIRT_IN \
CONFIG_REMOTE_IN \
$(USER_VARS)
Expand Down Expand Up @@ -274,12 +274,6 @@ DEFBINDMOUNTS := []
# Image Service Offload
DEFSERVICEOFFLOAD ?= false

# SNP
DEFSNPGUEST ?= false
# Based on SEV Secure Nested Paging Firmware ABI Specification section 4.3
# unspecified or == 0 --> 0x30000 i.e. Bit#17 is '1' and Bit#16 is '1' (SMT is allowed)
DEFSNPGUESTPOLICY ?= 0x30000

SED = sed

CLI_DIR = cmd
Expand Down Expand Up @@ -372,18 +366,6 @@ ifneq (,$(QEMUCMD))

CONFIGS += $(CONFIG_REMOTE)

CONFIG_FILE_CLH_SNP = configuration-clh-snp.toml
CONFIG_CLH_SNP = config/$(CONFIG_FILE_CLH_SNP)
CONFIG_CLH_SNP_IN = $(CONFIG_CLH_SNP).in

CONFIG_PATH_CLH_SNP = $(abspath $(CONFDIR)/$(CONFIG_FILE_CLH_SNP))
CONFIG_PATHS += $(CONFIG_PATH_CLH_SNP)

SYSCONFIG_CLH_SNP = $(abspath $(SYSCONFDIR)/$(CONFIG_FILE_CLH_SNP))
SYSCONFIG_PATHS += $(SYSCONFIG_CLH_SNP)

CONFIGS += $(CONFIG_CLH_SNP)

# qemu-specific options (all should be suffixed by "_QEMU")
DEFBLOCKSTORAGEDRIVER_QEMU := virtio-scsi
DEFBLOCKDEVICEAIO_QEMU := io_uring
Expand Down Expand Up @@ -422,6 +404,18 @@ ifneq (,$(CLHCMD))

CONFIGS += $(CONFIG_CLH)

CONFIG_FILE_CLH_SNP = configuration-clh-snp.toml
CONFIG_CLH_SNP = config/$(CONFIG_FILE_CLH_SNP)
CONFIG_CLH_SNP_IN = $(CONFIG_CLH_SNP).in

CONFIG_PATH_CLH_SNP = $(abspath $(CONFDIR)/$(CONFIG_FILE_CLH_SNP))
CONFIG_PATHS += $(CONFIG_PATH_CLH_SNP)

SYSCONFIG_CLH_SNP = $(abspath $(SYSCONFDIR)/$(CONFIG_FILE_CLH_SNP))
SYSCONFIG_PATHS += $(SYSCONFIG_CLH_SNP)

CONFIGS += $(CONFIG_CLH_SNP)

# CLH-specific options (all should be suffixed by "_CLH")
# currently, huge pages are required for virtiofsd support
DEFNETWORKMODEL_CLH := tcfilter
Expand Down Expand Up @@ -710,9 +704,6 @@ USER_VARS += DEFBINDMOUNTS
USER_VARS += DEFSERVICEOFFLOAD
USER_VARS += DEFVFIOMODE
USER_VARS += BUILDFLAGS
USER_VARS += DEFSNPGUESTPOLICY
USER_VARS += DEFSNPGUEST


V = @
Q = $(V:1=)
Expand Down
10 changes: 2 additions & 8 deletions src/runtime/config/configuration-clh-snp.toml.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Copyright (c) 2019 Ericsson Eurolab Deutschland GmbH
# Copyright (c) 2021 Adobe Inc.
# Copyright (c) 2023 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0
#
Expand Down Expand Up @@ -45,12 +44,7 @@ confidential_guest = true
# This is used in the CLH code path to request SEV SNP encryption. The function availableGuestProtection (see hypervisor_linux_amd64.go)
# that detects guest protection features hypervisor_linux_amd64.go only supports QEMU/KVM platforms, and currently there is no way to
# detect SEV SNP support with CLH/MSHV.
sev_snp_guest = @DEFSNPGUEST@

# SNP guest policy
# Based on SEV Secure Nested Paging Firmware ABI Specification section 4.3
# If it is unspecified or 0, it will default to 0x30000 (i.e. Bit#17 is '1' which is reserved and Bit#16 is '1' which means SMT is allowed).
snp_guest_policy=@DEFSNPGUESTPOLICY@
sev_snp_guest = true

# Enable running clh VMM as a non-root user.
# By default clh VMM run as root. When this is set to true, clh VMM process runs as
Expand Down
1 change: 0 additions & 1 deletion src/runtime/config/configuration-clh.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
path = "@CLHPATH@"
kernel = "@KERNELPATH_CLH@"
image = "@IMAGEPATH@"
#initrd = "@INITRDPATH@"

# rootfs filesystem type:
# - ext4 (default)
Expand Down
10 changes: 2 additions & 8 deletions src/runtime/config/configuration-qemu-snp.toml.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,15 @@ rootfs_type=@DEFROOTFSTYPE@
#
# Known limitations:
# * Does not work by design:
# - CPU Hotplug
# - CPU Hotplug
# - Memory Hotplug
# - NVDIMM devices
#
# Default false
confidential_guest = true

# enable SEV SNP VMs
sev_snp_guest = @DEFSNPGUEST@

# SNP guest policy
# Based on SEV Secure Nested Paging Firmware ABI Specification section 4.3
# If it is unspecified or 0, it will default to 0x30000 (i.e. Bit#17 is '1' which is reserved and Bit#16 is '1' which means SMT is allowed).
snp_guest_policy=@DEFSNPGUESTPOLICY@

sev_snp_guest = true

# Enable running QEMU VMM as a non-root user.
# By default QEMU VMM run as root. When this is set to true, QEMU VMM process runs as
Expand Down
2 changes: 2 additions & 0 deletions src/tarfs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ obj-m := tarfs.o
else

KDIR ?= /lib/modules/`uname -r`/build
KVER ?= `uname -r`
INSTALL_MOD_PATH ?= $$PWD/_install

default:
$(MAKE) -C $(KDIR) M=$$PWD

install:
$(MAKE) -C $(KDIR) M=$$PWD INSTALL_MOD_PATH=$(INSTALL_MOD_PATH) modules_install
depmod -a -b $(INSTALL_MOD_PATH) $(KVER)

clean:
rm -rf _install
Expand Down
18 changes: 16 additions & 2 deletions tools/osbuilder/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ TEST_RUNNER := $(MK_DIR)/tests/test_images.sh
ROOTFS_BUILDER := $(MK_DIR)/rootfs-builder/rootfs.sh
INITRD_BUILDER := $(MK_DIR)/initrd-builder/initrd_builder.sh
IMAGE_BUILDER := $(MK_DIR)/image-builder/image_builder.sh
IGVM_BUILDER := $(MK_DIR)/igvm-builder/igvm_builder.sh
IGVM_TOOL_SRC := $(MK_DIR)/igvm-tooling

DISTRO ?= ubuntu
BUILD_METHOD := distro
Expand All @@ -16,11 +18,17 @@ AGENT_INIT ?= no
USE_DOCKER ?= true
ROOTFS_BUILD_DEST := $(shell pwd)
IMAGES_BUILD_DEST := $(shell pwd)
IGVM_BUILD_DEST := $(shell pwd)
ROOTFS_MARKER_SUFFIX := _rootfs.done
TARGET_ROOTFS := $(ROOTFS_BUILD_DEST)/$(DISTRO)_rootfs
TARGET_ROOTFS_MARKER := $(ROOTFS_BUILD_DEST)/.$(DISTRO)$(ROOTFS_MARKER_SUFFIX)
TARGET_IMAGE := $(IMAGES_BUILD_DEST)/kata-containers.img
TARGET_INITRD := $(IMAGES_BUILD_DEST)/kata-containers-initrd.img
TARGET_IGVM := $(IGVM_BUILD_DEST)/kata-containers-igvm.img
TARGET_IGVM_MSMT := $(IGVM_BUILD_DEST)/igvm-measurement.cose
TARGET_IGVM_DEBUG := $(IGVM_BUILD_DEST)/kata-containers-igvm-debug.img
TARGET_IGVM_DEBUG_MSMT:= $(IGVM_BUILD_DEST)/igvm-debug-measurement.cose
TARGET_IGVM_LOG := $(IGVM_BUILD_DEST)/igvm.log

VERSION_FILE := ./VERSION
VERSION := $(shell grep -v ^\# $(VERSION_FILE))
Expand Down Expand Up @@ -86,7 +94,7 @@ endif
################################################################################

.PHONY: all
all: image initrd
all: image initrd igvm

rootfs-%: $(ROOTFS_BUILD_DEST)/.%$(ROOTFS_MARKER_SUFFIX)
@ # DONT remove. This is not cancellation rule.
Expand Down Expand Up @@ -156,6 +164,10 @@ $(DRACUT_OVERLAY_DIR):
mkdir -p $@/etc/modules-load.d
echo $(DRACUT_KMODULES) | tr " " "\n" > $@/etc/modules-load.d/kata-modules.conf

.PHONY: igvm
igvm: $(TARGET_IMAGE)
$(IGVM_BUILDER) -o $(IGVM_BUILD_DEST) -s 0

.PHONY: test
test:
$(TEST_RUNNER) "$(DISTRO)"
Expand Down Expand Up @@ -208,7 +220,9 @@ install-scripts:

.PHONY: clean
clean:
rm -rf $(TARGET_ROOTFS_MARKER) $(TARGET_ROOTFS) $(TARGET_IMAGE) $(TARGET_INITRD) $(DRACUT_OVERLAY_DIR)
rm -rf $(TARGET_ROOTFS_MARKER) $(TARGET_ROOTFS) $(TARGET_IMAGE) $(TARGET_INITRD) $(DRACUT_OVERLAY_DIR) $(TARGET_IGVM) $(TARGET_IGVM_DEBUG) $(TARGET_IGVM_MSMT) $(TARGET_IGVM_DEBUG_MSMT) $(TARGET_IGVM_LOG)
rm -rf $(IGVM_TOOL_SRC)
pip3 uninstall -y msigvm

# Prints the name of the variable passed as suffix to the print- target,
# E.g., if Makefile contains:
Expand Down
20 changes: 20 additions & 0 deletions tools/osbuilder/igvm-builder/azure-linux/config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
#
# Copyright (c) 2024 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0

# this is where the kernel-uvm package installation places bzImage, see SPEC file
bzimage_bin="/usr/share/cloud-hypervisor/bzImage"

igvm_extract_folder="igvm-tooling"
clh_acpi_tables_dir="${igvm_extract_folder}/src/igvm/acpi/acpi-clh/"
igvmgen_py_file="${igvm_extract_folder}/src/igvm/igvmgen.py"

igvm_vars="-kernel ${bzimage_bin} -boot_mode x64 -vtl 0 -svme 1 -encrypted_page 1 -pvalidate_opt 1 -acpi ${clh_acpi_tables_dir}"

igvm_kernel_params_common="dm-mod.create=\"dm-verity,,,ro,0 ${data_sectors} verity 1 /dev/vda1 /dev/vda2 ${data_block_size} ${hash_block_size} ${data_blocks} 0 sha256 ${root_hash} ${salt}\" \
root=/dev/dm-0 rootflags=data=ordered,errors=remount-ro ro rootfstype=ext4 panic=1 no_timer_check noreplace-smp systemd.unit=kata-containers.target systemd.mask=systemd-networkd.service \
systemd.mask=systemd-networkd.socket agent.enable_signature_verification=false"
igvm_kernel_prod_params="${igvm_kernel_params_common} quiet"
igvm_kernel_debug_params="${igvm_kernel_params_common} console=hvc0 systemd.log_target=console agent.log=debug agent.debug_console agent.debug_console_vport=1026"
25 changes: 25 additions & 0 deletions tools/osbuilder/igvm-builder/azure-linux/igvm_lib.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash
#
# Copyright (c) 2024 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0

install_igvm()
{
if [ -d ${igvm_extract_folder} ]; then
echo "${igvm_extract_folder} folder already exists, assuming tool is already installed"
return
fi

# the igvm tool on Azure Linux will soon be properly installed through dnf via kata-packages-uvm-build
# as of now, even when installing with pip3, we cannot delete the source folder as the ACPI tables are not being installed anywhere, hence relying on this folder
echo "Determining and downloading latest IGVM tooling release, and extracting including ACPI tables"
IGVM_VER=$(curl -sL "https://api.github.com/repos/microsoft/igvm-tooling/releases/latest" | jq -r .tag_name | sed 's/^v//')
curl -sL "https://github.com/microsoft/igvm-tooling/archive/refs/tags/${IGVM_VER}.tar.gz" | tar --no-same-owner -xz
mv igvm-tooling-${IGVM_VER} ${igvm_extract_folder}

echo "Installing IGVM module msigvm via pip3"
pushd ${igvm_extract_folder}/src
pip3 install --no-deps ./
popd
}
99 changes: 99 additions & 0 deletions tools/osbuilder/igvm-builder/igvm_builder.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env bash
#
# Copyright (c) 2024 Microsoft Corporation
#
# SPDX-License-Identifier: Apache-2.0

set -o errexit
set -o pipefail
set -o errtrace

[ -n "$DEBUG" ] && set -x

script_dir="$(dirname $(readlink -f $0))"

# distro-specific config file
typeset -r CONFIG_SH="config.sh"

# Name of an optional distro-specific file which, if it exists, must implement the
# install_igvm() function.
typeset -r LIB_SH="igvm_lib.sh"

build_igvm_distro()
{
distro_config_dir="${script_dir}/${distro}"

[ -d "${distro_config_dir}" ] || die "Could not find configuration directory '${distro_config_dir}'"

if [ -e "${distro_config_dir}/${LIB_SH}" ]; then
igvm_lib="${distro_config_dir}/${LIB_SH}"
echo "igvm_lib.sh file found. Loading content"
source "${igvm_lib}"
fi

root_hash_file="${script_dir}/../root_hash.txt"

if [ ! -f "${root_hash_file}" ]; then
echo "Could no find image root hash file '${root_hash_file}', aborting"
exit 1
fi

echo "Reading image dm-verity root hash values"
root_hash=$(sed -e 's/Root hash:\s*//g;t;d' "${root_hash_file}")
salt=$(sed -e 's/Salt:\s*//g;t;d' "${root_hash_file}")
data_blocks=$(sed -e 's/Data blocks:\s*//g;t;d' "${root_hash_file}")
data_block_size=$(sed -e 's/Data block size:\s*//g;t;d' "${root_hash_file}")
data_sectors_per_block=$((data_block_size / 512))
data_sectors=$((data_blocks * data_sectors_per_block))
hash_block_size=$(sed -e 's/Hash block size:\s*//g;t;d' "${root_hash_file}")

# Source config.sh from distro, depends on root_hash based variables here
igvm_config="${distro_config_dir}/${CONFIG_SH}"
source "${igvm_config}"

echo "Install IGVM tool"
install_igvm

echo "Build IGVM (debug) file and calculate reference measurements"
# we could call into the installed binary '~/.local/bin/igvmgen' when adding to PATH or, better, into 'python3 -m msigvm'
# however, as we still need the installation directory for the ACPI tables, we leave things as is for now
# at the same time we seem to need to call pip3 install for invoking the tool at all
python3 ${igvmgen_py_file} $igvm_vars -o kata-containers-igvm.img -measurement_file igvm-measurement.cose -append "$igvm_kernel_prod_params" -svn $SVN
python3 ${igvmgen_py_file} $igvm_vars -o kata-containers-igvm-debug.img -measurement_file igvm-debug-measurement.cose -append "$igvm_kernel_debug_params" -svn $SVN

if [ "${PWD}" -ef "$(readlink -f $OUT_DIR)" ]; then
echo "OUT_DIR matches with current dir, not moving build artifacts"
else
echo "Moving build artifacts to ${OUT_DIR}"
mv igvm-measurement.cose kata-containers-igvm.img igvm-debug-measurement.cose kata-containers-igvm-debug.img $OUT_DIR
fi
}

distro="azure-linux"

while getopts ":o:s:" OPTIONS; do
case "${OPTIONS}" in
o ) OUT_DIR=$OPTARG ;;
s ) SVN=$OPTARG ;;
\? )
echo "Error - Invalid Option: -$OPTARG" 1>&2
exit 1
;;
: )
echo "Error - Invalid Option: -$OPTARG requires an argument" 1>&2
exit 1
;;
esac
done

echo "IGVM builder script"
echo "-- OUT_DIR -> $OUT_DIR"
echo "-- SVN -> $SVN"
echo "-- distro -> $distro"

if [ -n "$distro" ]; then
build_igvm_distro
else
echo "distro must be specified"
exit 1
fi
Loading