diff --git a/Makefile b/Makefile index 57a03e8a..ed13c19e 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,9 @@ hypervisor: setup devtools hypervisor_dev: PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" ACE_DIR=$(ACE_DIR) $(MAKE) -C hypervisor dev +hypervisor_kvmtool: + PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" ACE_DIR=$(ACE_DIR) $(MAKE) -C hypervisor kvmtool + confidential_vms: setup devtools hypervisor tools PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" ACE_DIR=$(ACE_DIR) $(MAKE) -C $(CONFIDENTIAL_VMS_SOURCE_DIR)/linux_vm/ buildroot ;\ PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" ACE_DIR=$(ACE_DIR) $(MAKE) -C $(CONFIDENTIAL_VMS_SOURCE_DIR)/linux_vm/ overlay rootfs ;\ diff --git a/README.md b/README.md index 3ecf2f71..0f4a78db 100644 --- a/README.md +++ b/README.md @@ -122,16 +122,22 @@ You should see the output from the boot process and a promt to login to the hype # login: root, password: passwd ``` -To run the sample Linux OS as a confidential VM (login: root, password: passwd) execute: +To run the sample Linux OS as a confidential VM (login: root, password: passwd) execute. +This demonstrates automatic promotion of a VM to TVM: ``` -./run_linux_vm.sh +./run_linux_vm_qemu.sh +``` + +Run the sample Linux OS as a confidential VM using kvmtool. +``` +./run_linux_vm_kvmtool.sh ``` ## Local attestation Local attestation allows you to expose secrets (e.g., dm-crypt/LUKS key, TLS pre-shared key, etc) to your confidential VM in a secure way. Collect reference measurements of your virtual machines, like kernel, initrd, initial boot hart state. -Below as, an example, we just collect kernel measurement: +Below as, an example, we just collect the kernel measurement (for automatic promotion): ``` cove-tap-tool measure --kernel-file $ACE_DIR/confidential_vms/linux_vm/buildroot/images/Image # Example output: @@ -173,7 +179,7 @@ You should see the secret: [ 203.107150] Secret=0xc0ffee ``` -Integrating local attestation with dm-crypt/LUKS is work in progress. When finished, you will encrypt your rootfs and pass the decryption key via TAP. +Integrating local attestation with dm-crypt/LUKS is work in progress. When finished, you will be able to encrypt your rootfs and pass the decryption key via TAP. A script in initrd will then retrieve the decryption key from TAP and decrypt the rootfs. # License diff --git a/confidential-vms/linux_vm/Makefile b/confidential-vms/linux_vm/Makefile index 077c684e..2c24a8a3 100644 --- a/confidential-vms/linux_vm/Makefile +++ b/confidential-vms/linux_vm/Makefile @@ -19,6 +19,8 @@ LINUX_VM_OVERLAY_SOURCE_DIR ?= $(CONFIDENTIAL_VMS_LINUX_SOURCE_DIR)/overlay LINUX_VM_OVERLAY_WORK_DIR ?= $(CONFIDENTIAL_VMS_LINUX_WORK_DIR)/overlay LINUX_VM_OVERLAY_WORK_ROOT_DIR ?= $(LINUX_VM_OVERLAY_WORK_DIR)/root LINUX_VM_IMAGE ?= $(LINUX_VM_BUILDROOT_WORK_DIR)/images/Image +LINUX_VM_COVE_TAP_QEMU ?= $(LINUX_VM_BUILDROOT_WORK_DIR)/images/cove_tap_qemu +LINUX_VM_COVE_TAP_KVMTOOL ?= $(LINUX_VM_BUILDROOT_WORK_DIR)/images/cove_tap_kvmtool LINUX_VM_KERNEL_CONFIG ?= $(CONFIDENTIAL_VMS_LINUX_SOURCE_DIR)/configurations/linux64-defconfig LINUX_VM_BUILDROOT_CONFIG ?= $(CONFIDENTIAL_VMS_LINUX_SOURCE_DIR)/configurations/qemu_riscv64_virt_defconfig LINUX_VM_BUILDROOT_OVERRIDE_DIR ?= $(CONFIDENTIAL_VMS_LINUX_SOURCE_DIR)/configurations/package_override.dev @@ -76,11 +78,20 @@ overlay: setup cp $(LINUX_VM_ROOTFS_SOURCE_DIR)/*.sh $(HYPERVISOR_OVERLAY_ROOT_DIR)/ ;\ rm -rf $(HYPERVISOR_OVERLAY_LINUX_VM_DIR) && mkdir -p $(HYPERVISOR_OVERLAY_LINUX_VM_DIR) ;\ cp -r $(LINUX_VM_IMAGE) $(HYPERVISOR_OVERLAY_LINUX_VM_DIR)/ ;\ - cp -r $(LINUX_VM_BUILDROOT_ROOTFS) $(HYPERVISOR_OVERLAY_LINUX_VM_DIR) + cp -r $(LINUX_VM_BUILDROOT_ROOTFS) $(HYPERVISOR_OVERLAY_LINUX_VM_DIR) ;\ + rm -f $(LINUX_VM_COVE_TAP_QEMU) ;\ + $(eval $@_TMP = $(shell $(TOOLS_WORK_DIR)/cove-tap-tool measure --embedded-tap --kernel-file=$(LINUX_VM_IMAGE) | cut -d' ' -f2-;) ) + $(TOOLS_WORK_DIR)/cove-tap-tool generate --pcrs 4=$($@_TMP) --secrets 0=0xc0ffee --output-file=$(LINUX_VM_COVE_TAP_QEMU) + cp $(LINUX_VM_COVE_TAP_QEMU) $(HYPERVISOR_OVERLAY_LINUX_VM_DIR)/ + rm -f $(LINUX_VM_COVE_TAP_KVMTOOL) + $(eval $@_TMP = $(shell $(TOOLS_WORK_DIR)/cove-tap-tool measure --base-address=0x80200000 --kernel-file=$(LINUX_VM_IMAGE) | cut -d' ' -f2-;) ) + $(TOOLS_WORK_DIR)/cove-tap-tool generate --pcrs 4=$($@_TMP) --secrets 0=0xc0ffee --output-file=$(LINUX_VM_COVE_TAP_KVMTOOL) + cp $(LINUX_VM_COVE_TAP_KVMTOOL) $(HYPERVISOR_OVERLAY_LINUX_VM_DIR)/ + rootfs: overlay - PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" $(MAKE) -s -C $(LINUX_VM_BUILDROOT_SOURCE_DIR) RISCV=$(RISCV_GNU_TOOLCHAIN_WORK_DIR) PATH=$(PATH) ARCH=riscv64 KDIR=$(LINUX_DIR) CROSS_COMPILE=$(CROSS_COMPILE) O=$(LINUX_VM_BUILDROOT_WORK_DIR) rootfs-ext2; \ - cp -r $(LINUX_VM_BUILDROOT_WORK_DIR)/images/rootfs.cpio $(HYPERVISOR_OVERLAY_LINUX_VM_DIR); + PATH="$(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH)" $(MAKE) -s -C $(LINUX_VM_BUILDROOT_SOURCE_DIR) RISCV=$(RISCV_GNU_TOOLCHAIN_WORK_DIR) PATH=$(PATH) ARCH=riscv64 KDIR=$(LINUX_DIR) CROSS_COMPILE=$(CROSS_COMPILE) O=$(LINUX_VM_BUILDROOT_WORK_DIR) rootfs-ext2; + # cp -r $(LINUX_VM_BUILDROOT_WORK_DIR)/images/rootfs.cpio $(HYPERVISOR_OVERLAY_LINUX_VM_DIR); clean: rm -rf $(ACE_DIR) diff --git a/confidential-vms/linux_vm/configurations/linux64-defconfig b/confidential-vms/linux_vm/configurations/linux64-defconfig index 22a06ecb..0b47074e 100644 --- a/confidential-vms/linux_vm/configurations/linux64-defconfig +++ b/confidential-vms/linux_vm/configurations/linux64-defconfig @@ -327,6 +327,7 @@ CONFIG_FPU=y # CONFIG_RISCV_COVE_GUEST is not set CONFIG_RISCV_COVE_GUEST=y CONFIG_RISCV_COVE_GUEST_PROMOTE=y +CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP=y # end of Confidential VM Extension(CoVE) Support # end of Platform type diff --git a/confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_kvmtool.sh b/confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_kvmtool.sh new file mode 100755 index 00000000..d86f25ca --- /dev/null +++ b/confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_kvmtool.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: 2023 IBM Corporation +# SPDX-FileContributor: Wojciech Ozga , IBM Research - Zurich +# SPDX-License-Identifier: Apache-2.0 + +KERNEL=/root/linux_vm/Image +TAP=/root/linux_vm/cove_tap_kvmtool + +./lkvm-static run -c2 --console virtio --cove-vm --cove-tap=${TAP} --cove-single-step-init -p "console=ttyS0 ro root=/dev/vda swiotlb=mmnn,force" -k ${KERNEL} --virtio-transport=pci diff --git a/confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm.sh b/confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_qemu.sh similarity index 100% rename from confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm.sh rename to confidential-vms/linux_vm/hypervisor_rootfs/run_linux_vm_qemu.sh diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 97340f77..ad5d0373 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -20,6 +20,8 @@ HYPERVISOR_OVERLAY_ROOT_DIR ?= $(HYPERVISOR_OVERLAY_DIR)/root HYPERVISOR_PATCHES_DIR ?= $(MAKEFILE_SOURCE_DIR)/patches HYPERVISOR_LINUX_PATCH ?= $(HYPERVISOR_PATCHES_DIR)/linux/6.3-rc4/ +KVMTOOL_WORK_DIR ?= $(HYPERVISOR_WORK_DIR)/kvmtool + BUILDROOT_WORK_DIR ?= $(HYPERVISOR_WORK_DIR)/buildroot RISCV_GNU_TOOLCHAIN_WORK_DIR ?= $(ACE_DIR)/riscv-gnu-toolchain/ export PATH := $(RISCV_GNU_TOOLCHAIN_WORK_DIR)/bin:$(PATH) @@ -52,11 +54,12 @@ buildroot: setup $(MAKE) -s -C $(BUILDROOT_SOURCE_DIR) RISCV=$(RISCV_GNU_TOOLCHAIN_WORK_DIR) PATH=$(PATH) O=$(BUILDROOT_WORK_DIR) BR2_JLEVEL=0 ;\ fi -overlay: +overlay: kvmtool echo "Setting up the content of the hypervisor's root directory" ;\ mkdir -p $(HYPERVISOR_OVERLAY_ROOT_DIR); \ mkdir -p $(HYPERVISOR_OVERLAY_DIR); \ - cp $(HYPERVISOR_ROOTFS_SOURCE_DIR)/*.sh $(HYPERVISOR_OVERLAY_ROOT_DIR)/ + cp $(HYPERVISOR_ROOTFS_SOURCE_DIR)/*.sh $(HYPERVISOR_OVERLAY_ROOT_DIR)/; \ + cp ${KVMTOOL_WORK_DIR}/kvmtool/lkvm-static $(HYPERVISOR_OVERLAY_ROOT_DIR)/; dev: sed "s@^BR2_PACKAGE_OVERRIDE_FILE=.*@BR2_PACKAGE_OVERRIDE_FILE=\"$(HYPERVISOR_BUILDROOT_OVERRIDE_DIR)\"@g" -i $(BUILDROOT_WORK_DIR)/.config; \ @@ -67,6 +70,26 @@ rootfs: overlay echo "Generating hypervisor's root filesystem" ;\ $(MAKE) -s -C $(BUILDROOT_SOURCE_DIR) RISCV=$(RISCV_GNU_TOOLCHAIN_WORK_DIR) PATH=$(PATH) O=$(BUILDROOT_WORK_DIR) rootfs-ext2 +kvmtool: + mkdir -p $(KVMTOOL_WORK_DIR) && cd $(KVMTOOL_WORK_DIR) ;\ + if [ ! -f "${KVMTOOL_WORK_DIR}/dtc/build/libfdt.so" ]; then \ + rm -rf ${KVMTOOL_WORK_DIR}/dtc ;\ + git clone git://git.kernel.org/pub/scm/utils/dtc/dtc.git ;\ + cd dtc ;\ + ARCH=riscv CC="${CROSS_COMPILE}gcc -mabi=${PLATFORM_RISCV_ABI} -march=${PLATFORM_RISCV_ISA}" make NO_PYTHON=1 NO_YAML=1 DESTDIR=$($CC -print-sysroot) PREFIX=${KVMTOOL_WORK_DIR}/dtc/build LIBDIR=${KVMTOOL_WORK_DIR}/dtc/build/$($CC -dumpmachine) install-lib install-includes ;\ + cp ${KVMTOOL_WORK_DIR}/dtc/build/include/* ${KVMTOOL_WORK_DIR}/dtc/build/ ;\ + cd .. ;\ + fi ;\ + if [ ! -f "${KVMTOOL_WORK_DIR}/kvmtool/lkvm-static" ]; then \ + rm -rf ${KVMTOOL_WORK_DIR}/kvmtool ;\ + git clone -b cove-integration-03072023 https://github.com/wojciechozga/kvmtool.git ;\ + rm -f $(KVMTOOL_WORK_DIR)/kvmtool/lkvm-static ;\ + cd $(KVMTOOL_WORK_DIR)/kvmtool ;\ + ARCH=riscv LIBFDT_DIR=${KVMTOOL_WORK_DIR}/dtc/build/ make lkvm-static -j$(nproc) ;\ + ${CROSS_COMPILE}strip lkvm-static ;\ + cd .. ;\ + fi + clean: rm -rf $(HYPERVISOR_WORK_DIR) diff --git a/hypervisor/configurations/linux64-defconfig b/hypervisor/configurations/linux64-defconfig index a1579730..7390482b 100644 --- a/hypervisor/configurations/linux64-defconfig +++ b/hypervisor/configurations/linux64-defconfig @@ -326,6 +326,9 @@ CONFIG_FPU=y CONFIG_RISCV_COVE_HOST=y # CONFIG_RISCV_COVE_GUEST is not set +CONFIG_RISCV_COVE_GUEST=n +CONFIG_RISCV_COVE_GUEST_PROMOTE=n +CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP=n # end of Confidential VM Extension(CoVE) Support # end of Platform type diff --git a/hypervisor/patches/linux/6.3-rc4/0002-ace.patch b/hypervisor/patches/linux/6.3-rc4/0002-ace.patch index 7048ae3a..2319566a 100644 --- a/hypervisor/patches/linux/6.3-rc4/0002-ace.patch +++ b/hypervisor/patches/linux/6.3-rc4/0002-ace.patch @@ -1,67 +1,37 @@ diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig -index 2ca9e01ad0e8..317e0f41ac9b 100644 +index 2ca9e01ad0e8..81cad924145b 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig -@@ -526,6 +526,13 @@ config RISCV_COVE_GUEST +@@ -526,6 +526,21 @@ config RISCV_COVE_GUEST help Enables support for running TVMs on platforms supporting CoVE. - + ++config RISCV_COVE_GUEST_EMBEDDED_TAP ++ bool "Guest Support for embedded TVM Attestation Payload (TAP)" ++ default n ++ select RISCV_COVE_GUEST ++ help ++ Creates placeholder in the kernel image to embed TAP. ++ +config RISCV_COVE_GUEST_PROMOTE + bool "Automatic promotion of VM to TVM for Confidential VM Extension(CoVE)" + default n + select RISCV_COVE_GUEST ++ select RISCV_COVE_GUEST_EMBEDDED_TAP + help + VM requests promotion to TVM during early boot on platforms supporting CoVE. + endmenu # "Confidential VM Extension(CoVE) Support" - + endmenu # "Platform type" -diff --git a/arch/riscv/cove/core.c b/arch/riscv/cove/core.c -index 582feb1c6c8d..16d607113366 100644 ---- a/arch/riscv/cove/core.c -+++ b/arch/riscv/cove/core.c -@@ -13,6 +13,8 @@ - #include - #include - -+extern char __cove_tap_start[]; -+ - static bool is_tvm; - - bool is_cove_guest(void) -diff --git a/arch/riscv/include/asm/cove_promote.h b/arch/riscv/include/asm/cove_promote.h -new file mode 100644 -index 000000000000..1472cbaf071f ---- /dev/null -+++ b/arch/riscv/include/asm/cove_promote.h -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * Definitions for promotion of VM to TVM. -+ * -+ * Copyright (c) 2024 IBM Corp. -+ * -+ * Authors: -+ * Wojciech Ozga -+ */ -+ -+#ifndef __RISCV_COVE_PROMOTE_H__ -+#define __RISCV_COVE_PROMOTE_H__ -+ -+#ifdef CONFIG_RISCV_COVE_GUEST_PROMOTE -+#define COVE_PROMOTE_SBI_EXT_ID 0x434F5648 -+#define COVE_PROMOTE_SBI_FID 0x15 -+#endif /* CONFIG_RISCV_COVE_GUEST_PROMOTE */ -+ -+#endif /* __RISCV_COVE_PROMOTE_H__ */ diff --git a/arch/riscv/include/asm/kvm_cove.h b/arch/riscv/include/asm/kvm_cove.h -index afaea7c621bb..f9ce258dfab8 100644 +index afaea7c621bb..f05c9a7191bc 100644 --- a/arch/riscv/include/asm/kvm_cove.h +++ b/arch/riscv/include/asm/kvm_cove.h @@ -19,6 +19,13 @@ #include #include - + +#define KVM_COVE_TSM_CAP_PROMOTE_TVM 0x0 +#define KVM_COVE_TSM_CAP_ATTESTATION_LOCAL 0x1 +#define KVM_COVE_TSM_CAP_ATTESTATION_REMOTE 0x2 @@ -72,24 +42,74 @@ index afaea7c621bb..f9ce258dfab8 100644 #define KVM_COVE_PAGE_SIZE_4K (1UL << 12) #define KVM_COVE_PAGE_SIZE_2MB (1UL << 21) #define KVM_COVE_PAGE_SIZE_1GB (1UL << 30) -@@ -126,11 +133,15 @@ static inline bool is_cove_vcpu(struct kvm_vcpu *vcpu) +@@ -85,6 +92,9 @@ struct kvm_cove_tvm_context { + /* TODO: This is not really a VMID as TSM returns the page owner ID instead of VMID */ + unsigned long tvm_guest_id; + ++ /* Address of TVM Attestation Payload (TAP) */ ++ unsigned long cove_tap_addr; ++ + /* Pages where TVM page table is stored */ + struct kvm_riscv_cove_page pgtable; + +@@ -115,7 +125,8 @@ struct kvm_cove_tvm_context { + + static inline bool is_cove_vm(struct kvm *kvm) + { +- return kvm->arch.vm_type == KVM_VM_TYPE_RISCV_COVE; ++ return kvm->arch.vm_type == KVM_VM_TYPE_RISCV_COVE_MULTI_STEP_INIT || \ ++ kvm->arch.vm_type == KVM_VM_TYPE_RISCV_COVE_SINGLE_STEP_INIT; + } + + static inline bool is_cove_vcpu(struct kvm_vcpu *vcpu) +@@ -123,20 +134,45 @@ static inline bool is_cove_vcpu(struct kvm_vcpu *vcpu) + return is_cove_vm(vcpu->kvm); + } + ++static inline bool is_cove_vm_initializing(struct kvm *kvm) ++{ ++ return is_cove_vm(kvm) && !kvm->arch.tvmc->finalized_done; ++} ++ ++static inline bool is_cove_vm_multi_step_initializing(struct kvm *kvm) ++{ ++ return kvm->arch.vm_type == KVM_VM_TYPE_RISCV_COVE_MULTI_STEP_INIT && \ ++ !kvm->arch.tvmc->finalized_done; ++} ++ ++static inline bool is_cove_vm_single_step_initializing(struct kvm *kvm) ++{ ++ return kvm->arch.vm_type == KVM_VM_TYPE_RISCV_COVE_SINGLE_STEP_INIT && \ ++ !kvm->arch.tvmc->finalized_done; ++} ++ ++static inline bool is_cove_vm_finalized(struct kvm *kvm) ++{ ++ return is_cove_vm(kvm) && kvm->arch.tvmc->finalized_done; ++} ++ #ifdef CONFIG_RISCV_COVE_HOST - + bool kvm_riscv_cove_enabled(void); +bool kvm_riscv_cove_capability(unsigned long cap); int kvm_riscv_cove_init(void); - + /* TVM related functions */ void kvm_riscv_cove_vm_destroy(struct kvm *kvm); -int kvm_riscv_cove_vm_init(struct kvm *kvm); -+int kvm_riscv_cove_vm_single_step_init(struct kvm_vcpu *vcpu, -+ unsigned long fdt_address, -+ unsigned long tap_addr); ++int kvm_riscv_cove_vm_single_step_init(struct kvm *kvm); +int kvm_riscv_cove_vm_multi_step_init(struct kvm *kvm); - + /* TVM VCPU related functions */ void kvm_riscv_cove_vcpu_destroy(struct kvm_vcpu *vcpu); -@@ -158,13 +169,20 @@ int kvm_riscv_cove_aia_convert_imsic(struct kvm_vcpu *vcpu, phys_addr_t imsic_pa + int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu); + void kvm_riscv_cove_vcpu_load(struct kvm_vcpu *vcpu); + void kvm_riscv_cove_vcpu_put(struct kvm_vcpu *vcpu); ++void kvm_riscv_cove_gstage_preload(struct kvm_vcpu *vcpu); + void kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_trap *trap); + int kvm_riscv_cove_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run); + +@@ -158,19 +194,22 @@ int kvm_riscv_cove_aia_convert_imsic(struct kvm_vcpu *vcpu, phys_addr_t imsic_pa int kvm_riscv_cove_vcpu_imsic_addr(struct kvm_vcpu *vcpu); #else static inline bool kvm_riscv_cove_enabled(void) {return false; }; @@ -97,33 +117,33 @@ index afaea7c621bb..f9ce258dfab8 100644 static inline int kvm_riscv_cove_init(void) { return -1; } static inline void kvm_riscv_cove_hardware_disable(void) {} static inline int kvm_riscv_cove_hardware_enable(void) {return 0; } - + /* TVM related functions */ static inline void kvm_riscv_cove_vm_destroy(struct kvm *kvm) {} -static inline int kvm_riscv_cove_vm_init(struct kvm *kvm) {return -1; } -+static inline int kvm_riscv_cove_vm_single_step_init(struct kvm_vcpu *vcpu, -+ unsigned long fdt_address, -+ unsigned long tap_addr) -+{ -+ return -1; -+} -+static inline int kvm_riscv_cove_vm_multi_step_init(struct kvm *kvm) {return -1; } - ++static inline int kvm_riscv_cove_vm_single_step_init(struct kvm *kvm) { return -1; } ++static inline int kvm_riscv_cove_vm_multi_step_init(struct kvm *kvm) { return -1; } + /* TVM VCPU related functions */ static inline void kvm_riscv_cove_vcpu_destroy(struct kvm_vcpu *vcpu) {} + static inline int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) {return -1; } + static inline void kvm_riscv_cove_vcpu_load(struct kvm_vcpu *vcpu) {} + static inline void kvm_riscv_cove_vcpu_put(struct kvm_vcpu *vcpu) {} ++static inline void kvm_riscv_cove_gstage_preload(struct kvm_vcpu *vcpu) {} + static inline void kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_trap *trap) {} + static inline int kvm_riscv_cove_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) + { diff --git a/arch/riscv/include/asm/kvm_cove_sbi.h b/arch/riscv/include/asm/kvm_cove_sbi.h -index c9302650adc8..1314227adfad 100644 +index c9302650adc8..c14366f2916a 100644 --- a/arch/riscv/include/asm/kvm_cove_sbi.h +++ b/arch/riscv/include/asm/kvm_cove_sbi.h -@@ -78,6 +78,10 @@ int sbi_covh_tvm_demote_page(unsigned long tvmid, +@@ -78,6 +78,8 @@ int sbi_covh_tvm_demote_page(unsigned long tvmid, int sbi_covh_tvm_remove_pages(unsigned long tvmid, unsigned long tvm_base_page_addr, unsigned long len); -+int sbi_covh_tsm_promote_to_tvm(unsigned long fdt_address, -+ unsigned long tap_addr, -+ unsigned long sepc, -+ unsigned long *tvmid); - ++int sbi_covh_tsm_promote_to_tvm(unsigned long fdt_address, unsigned long tap_addr, ++ unsigned long sepc, unsigned long *tvmid); + /* Functions related to CoVE Interrupt Management(COVI) Extension */ int sbi_covi_tvm_aia_init(unsigned long tvm_gid, struct sbi_cove_tvm_aia_params *tvm_aia_params); diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -136,117 +156,118 @@ index 5b37a12337b1..763a931407f3 100644 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_covg; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_covh; #endif - + #endif /* __RISCV_KVM_VCPU_SBI_H__ */ diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h -index 03b0cc871242..01e9e5b1d7a2 100644 +index 03b0cc871242..b8e43c68d552 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h -@@ -374,6 +374,7 @@ enum sbi_ext_covh_fid { - SBI_EXT_COVH_TVM_PROMOTE_PAGE, - SBI_EXT_COVH_TVM_DEMOTE_PAGE, - SBI_EXT_COVH_TVM_REMOVE_PAGES, +@@ -360,6 +360,7 @@ enum sbi_ext_covh_fid { + SBI_EXT_COVH_TSM_LOCAL_FENCE, + SBI_EXT_COVH_CREATE_TVM, + SBI_EXT_COVH_FINALIZE_TVM, + SBI_EXT_COVH_PROMOTE_TO_TVM, - }; - - enum sbi_ext_covi_fid { + SBI_EXT_COVH_DESTROY_TVM, + SBI_EXT_COVH_TVM_ADD_MEMORY_REGION, + SBI_EXT_COVH_TVM_ADD_PGT_PAGES, @@ -410,9 +411,15 @@ struct sbi_cove_tsm_info { /* Current state of the TSM */ enum sbi_cove_tsm_state tstate; - + + /* TSM implementation identifier */ + uint32_t impl_id; + /* Version of the loaded TSM */ uint32_t version; - + + /* Capabilities of the TSM */ + unsigned long capabilities; + /* Number of 4K pages required per TVM */ unsigned long tvm_pages_needed; - + diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h -index 2a2434136e39..679a6727a143 100644 +index 2a2434136e39..5514e0dea69b 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h -@@ -149,6 +149,7 @@ enum KVM_RISCV_SBI_EXT_ID { +@@ -99,6 +99,14 @@ struct kvm_riscv_timer { + }; + + /* Memory region details of a CoVE guest that is measured at boot time */ ++enum KVM_RISCV_COVE_REGION { ++ KVM_RISCV_COVE_REGION_FIRMWARE = 0, ++ KVM_RISCV_COVE_REGION_KERNEL, ++ KVM_RISCV_COVE_REGION_FDT, ++ KVM_RISCV_COVE_REGION_INITRD, ++ KVM_RISCV_COVE_REGION_COVE_TAP, ++}; ++ + struct kvm_riscv_cove_measure_region { + /* Address of the user space where the VM code/data resides */ + unsigned long userspace_addr; +@@ -108,6 +116,9 @@ struct kvm_riscv_cove_measure_region { + + /* Size of the region */ + unsigned long size; ++ ++ /* Type of the region */ ++ enum KVM_RISCV_COVE_REGION type; + }; + + /* +@@ -149,6 +160,7 @@ enum KVM_RISCV_SBI_EXT_ID { KVM_RISCV_SBI_EXT_VENDOR, KVM_RISCV_SBI_EXT_DBCN, KVM_RISCV_SBI_EXT_COVG, + KVM_RISCV_SBI_EXT_COVH, KVM_RISCV_SBI_EXT_MAX, }; - + diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S -index 4bf6c449d78b..bc7b9aacea51 100644 +index 4bf6c449d78b..65655bb2382a 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include "efi-header.S" - - __HEAD -@@ -198,6 +199,18 @@ ENTRY(_start_kernel) +@@ -198,6 +198,24 @@ ENTRY(_start_kernel) csrw CSR_IE, zero csrw CSR_IP, zero - -+#ifdef CONFIG_RISCV_COVE_GUEST_PROMOTE -+ mv s1, a0 -+ mv s2, a1 -+ li a7, COVE_PROMOTE_SBI_EXT_ID -+ li a6, COVE_PROMOTE_SBI_FID -+ mv a0, a1 -+ la a1, __cove_tap_start + ++#if defined(CONFIG_RISCV_COVE_GUEST_PROMOTE) && !defined(CONFIG_RISCV_M_MODE) ++ mv s0, a0 ++ mv s1, a1 ++ /* Request hypervisor to promote to TVM */ ++ li a7, 0x434F5648 /* SBI_EXT_COVH */ ++ li a6, 0x7 /* SBI_EXT_COVH_PROMOTE_TO_TVM */ ++ mv a0, a1 /* DTB physical address */ ++#ifdef CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP ++ la a1, __cove_tap_start /* TAP physical address */ ++#else ++ li a1, 0 ++#endif /* CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP */ + ecall -+ mv a0, s1 -+ mv a1, s2 -+#endif ++ /* Attestation reflects the result of promotion, so ignore it */ ++ mv a0, s0 ++ mv a1, s1 ++#endif /* CONFIG_RISCV_COVE_GUEST_PROMOTE */ + #ifdef CONFIG_RISCV_M_MODE /* flush the instruction cache */ fence.i -diff --git a/arch/riscv/kernel/vmlinux-xip.lds.S b/arch/riscv/kernel/vmlinux-xip.lds.S -index eab9edc3b631..e8b14457d2be 100644 ---- a/arch/riscv/kernel/vmlinux-xip.lds.S -+++ b/arch/riscv/kernel/vmlinux-xip.lds.S -@@ -58,6 +58,17 @@ SECTIONS - } - _exiprom = .; /* End of XIP ROM area */ - -+#ifdef CONFIG_RISCV_COVE_GUEST -+ . = ALIGN(4096); -+ .cove_tvm_attestation_payload : { -+ __cove_tap_start = .; -+ LONG(0xace0ace0) -+ SHORT(0x0FFA) -+ FILL(0x00) -+ . += 4090; -+ __cove_tap_end = .; -+ } -+#endif - - /* - * From this point, stuff is considered writable and will be copied to RAM diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S -index 53a8ad65b255..a2af65f95034 100644 +index 53a8ad65b255..1cd955779776 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -113,6 +113,18 @@ SECTIONS } __init_end = .; - -+#ifdef CONFIG_RISCV_COVE_GUEST + ++#ifdef CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP + . = ALIGN(4096); + .cove_tvm_attestation_payload : { + __cove_tap_start = .; + LONG(0xace0ace0) + SHORT(0x0FFA) + FILL(0x00) -+ . += 4090; ++ . += 4090; + __cove_tap_end = .; + } +#endif @@ -265,13 +286,24 @@ index 31f4dbd97b03..fba7ebd0cd72 100644 -kvm-$(CONFIG_RISCV_COVE_HOST) += cove_sbi.o cove.o vcpu_sbi_covg.o +kvm-$(CONFIG_RISCV_COVE_HOST) += cove_sbi.o cove.o vcpu_sbi_covg.o vcpu_sbi_covh.o diff --git a/arch/riscv/kvm/cove.c b/arch/riscv/kvm/cove.c -index ba596b7f2240..ed7dc0fbf08b 100644 +index ba596b7f2240..e364fc9153b9 100644 --- a/arch/riscv/kvm/cove.c +++ b/arch/riscv/kvm/cove.c -@@ -150,6 +150,11 @@ __always_inline bool kvm_riscv_cove_enabled(void) +@@ -134,6 +134,10 @@ static int cove_convert_pages(unsigned long phys_addr, unsigned long npages, boo + if (!IS_ALIGNED(phys_addr, PAGE_SIZE)) + return -EINVAL; + ++ if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_MEMORY_ALLOCATION)) { ++ return -EOPNOTSUPP; ++ } ++ + rc = sbi_covh_tsm_convert_pages(phys_addr, npages); + if (rc) + return rc; +@@ -150,6 +154,11 @@ __always_inline bool kvm_riscv_cove_enabled(void) return riscv_cove_enabled; } - + +__always_inline bool kvm_riscv_cove_capability(unsigned long cap) +{ + return tinfo.capabilities & BIT(cap); @@ -280,8 +312,61 @@ index ba596b7f2240..ed7dc0fbf08b 100644 static void kvm_cove_imsic_clone(void *info) { int rc; -@@ -589,9 +594,9 @@ void noinstr kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_ - +@@ -560,15 +569,30 @@ int kvm_riscv_cove_handle_pagefault(struct kvm_vcpu *vcpu, gpa_t gpa, + return kvm_riscv_cove_gstage_map(vcpu, gpa, hva); + } + ++void kvm_riscv_cove_gstage_preload(struct kvm_vcpu *vcpu) { ++ struct kvm_memory_slot *memslot; ++ unsigned long hva, gpa, page; ++ int bkt; ++ ++ kvm_for_each_memslot(memslot, bkt, kvm_memslots(vcpu->kvm)) { ++ for (page = 0; page < memslot->npages; page++) { ++ gpa = gfn_to_gpa(memslot->base_gfn) + page * PAGE_SIZE; ++ hva = gfn_to_hva_memslot_prot(memslot, gpa_to_gfn(gpa), NULL); ++ if (!kvm_is_error_hva(hva)) ++ kvm_riscv_gstage_map(vcpu, memslot, gpa, hva, NULL); ++ } ++ } ++} ++ + void noinstr kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_trap *trap) + { +- int rc; +- struct kvm *kvm = vcpu->kvm; +- struct kvm_cove_tvm_context *tvmc; + struct kvm_cpu_context *cntx = &vcpu->arch.guest_context; +- void *nshmem; +- struct kvm_guest_timer *gt = &kvm->arch.timer; + struct kvm_cove_tvm_vcpu_context *tvcpuc = vcpu->arch.tc; ++ struct kvm_guest_timer *gt = &vcpu->kvm->arch.timer; ++ struct kvm_cove_tvm_context *tvmc; ++ struct kvm *kvm = vcpu->kvm; ++ void *nshmem; ++ int rc; + + if (!kvm->arch.tvmc) + return; +@@ -578,8 +602,14 @@ void noinstr kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_ + nshmem = nacl_shmem(); + /* Invoke finalize to mark TVM is ready run for the first time */ + if (unlikely(!tvmc->finalized_done)) { +- +- rc = sbi_covh_tsm_finalize_tvm(tvmc->tvm_guest_id, cntx->sepc, cntx->a1); ++ if (is_cove_vm_multi_step_initializing(vcpu->kvm)) { ++ rc = sbi_covh_tsm_finalize_tvm(tvmc->tvm_guest_id, cntx->sepc, cntx->a1); ++ } else if (is_cove_vm_single_step_initializing(vcpu->kvm)) { ++ rc = sbi_covh_tsm_promote_to_tvm(cntx->a1, tvmc->cove_tap_addr, cntx->sepc, ++ &tvmc->tvm_guest_id); ++ } else { ++ rc = -EOPNOTSUPP; ++ } + if (rc) { + kvm_err("TVM Finalized failed with %d\n", rc); + return; +@@ -589,9 +619,9 @@ void noinstr kvm_riscv_cove_vcpu_switchto(struct kvm_vcpu *vcpu, struct kvm_cpu_ + /* * Bind the vsfile here instead during the new vsfile allocation because - * COVH bind call requires the TVM to be in finalized state. @@ -292,8 +377,23 @@ index ba596b7f2240..ed7dc0fbf08b 100644 tvcpuc->imsic.bind_required = false; rc = kvm_riscv_cove_vcpu_imsic_bind(vcpu, BIT(tvcpuc->imsic.vsfile_hgei)); if (rc) { -@@ -628,12 +633,12 @@ void kvm_riscv_cove_vcpu_destroy(struct kvm_vcpu *vcpu) - +@@ -619,21 +649,27 @@ void kvm_riscv_cove_vcpu_destroy(struct kvm_vcpu *vcpu) + struct kvm_cove_tvm_vcpu_context *tvcpuc = vcpu->arch.tc; + struct kvm *kvm = vcpu->kvm; + ++ if (tvcpuc == NULL) ++ return; ++ + /* + * Just add the vcpu state pages to a list at this point as these can not + * be claimed until tvm is destroyed. * + */ + list_add(&tvcpuc->vcpu_state.link, &kvm->arch.tvmc->reclaim_pending_pages); ++ ++ vcpu->arch.tc = NULL; ++ kfree(tvcpuc); + } + int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) { - int rc; @@ -305,85 +405,93 @@ index ba596b7f2240..ed7dc0fbf08b 100644 + struct page *vcpus_page; + struct kvm *kvm; + int rc; - + if (!vcpu) return -EINVAL; -@@ -654,15 +659,20 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) +@@ -654,6 +690,14 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) if (!tvcpuc) return -ENOMEM; - -- vcpus_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, + + tvcpuc->vcpu = vcpu; + tvcpuc->vcpu_state.npages = tinfo.tvcpu_pages_needed; + vcpu->arch.tc = tvcpuc; + -+ if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_MEMORY_ALLOCATION)) { ++ if (!is_cove_vm_multi_step_initializing(vcpu->kvm)) { + return 0; + } + -+ vcpus_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, + vcpus_page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order_num_pages(tinfo.tvcpu_pages_needed)); if (!vcpus_page) { - rc = -ENOMEM; +@@ -661,8 +705,6 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) goto alloc_page_failed; } -- + - tvcpuc->vcpu = vcpu; - tvcpuc->vcpu_state.npages = tinfo.tvcpu_pages_needed; tvcpuc->vcpu_state.page = vcpus_page; vcpus_phys_addr = page_to_phys(vcpus_page); - -@@ -674,8 +684,6 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) + +@@ -674,8 +716,6 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) if (rc) goto vcpu_create_failed; - + - vcpu->arch.tc = tvcpuc; - return 0; - + vcpu_create_failed: -@@ -686,6 +694,7 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) +@@ -686,6 +726,7 @@ int kvm_riscv_cove_vcpu_init(struct kvm_vcpu *vcpu) __free_pages(vcpus_page, get_order_num_pages(tinfo.tvcpu_pages_needed)); - + alloc_page_failed: + vcpu->arch.tc = NULL; kfree(tvcpuc); return rc; } -@@ -877,7 +886,7 @@ void kvm_riscv_cove_vm_destroy(struct kvm *kvm) +@@ -706,6 +747,13 @@ int kvm_riscv_cove_vm_measure_pages(struct kvm *kvm, struct kvm_riscv_cove_measu + return -EINVAL; + } + ++ if (mr->type == KVM_RISCV_COVE_REGION_COVE_TAP) { ++ tvmc->cove_tap_addr = mr->gpa; ++ } ++ ++ if (!is_cove_vm_multi_step_initializing(kvm)) ++ return 0; ++ + num_pages = bytes_to_pages(mr->size); + conf = &tvmc->confidential_region; + +@@ -844,6 +892,9 @@ void kvm_riscv_cove_vm_destroy(struct kvm *kvm) + return; + } + ++ if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_MEMORY_ALLOCATION)) ++ goto deallocate_tvmc; ++ + cove_delete_page_list(kvm, &tvmc->reclaim_pending_pages, false); + cove_delete_page_list(kvm, &tvmc->measured_pages, false); + cove_delete_page_list(kvm, &tvmc->zero_pages, true); +@@ -869,22 +920,48 @@ void kvm_riscv_cove_vm_destroy(struct kvm *kvm) + if (rc) + goto reclaim_failed; + ++deallocate_tvmc: + kfree(tvmc); +- + return; + + reclaim_failed: kvm_err("Memory reclaim failed with rc %d\n", rc); } - + -int kvm_riscv_cove_vm_init(struct kvm *kvm) -+int kvm_riscv_cove_vm_multi_step_init(struct kvm *kvm) ++int kvm_riscv_cove_vm_single_step_init(struct kvm *kvm) { struct kvm_cove_tvm_context *tvmc; - struct page *tvms_page, *pgt_page; -@@ -885,6 +894,10 @@ int kvm_riscv_cove_vm_init(struct kvm *kvm) - unsigned long gstage_pgd_size = kvm_riscv_gstage_pgd_size(); - int rc = 0; - -+ // Multi-step TVM creation requires TSM that supports dynamic page conversion -+ if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_MEMORY_ALLOCATION)) -+ return -EOPNOTSUPP; -+ - tvmc = kzalloc(sizeof(*tvmc), GFP_KERNEL); - if (!tvmc) - return -ENOMEM; -@@ -980,6 +993,65 @@ int kvm_riscv_cove_vm_init(struct kvm *kvm) - return rc; - } - -+int kvm_riscv_cove_vm_single_step_init(struct kvm_vcpu *vcpu, unsigned long fdt_address, -+ unsigned long tap_addr) -+{ -+ struct kvm_cpu_context *cp = &vcpu->arch.guest_context; -+ unsigned long tvm_gid, target_vcpuid; -+ struct kvm_cove_tvm_context *tvmc; -+ struct kvm_vcpu *target_vcpu; -+ struct kvm *kvm = vcpu->kvm; -+ void *nshmem = nacl_shmem(); -+ int rc = 0, gpr_id, offset; +- struct page *tvms_page, *pgt_page; +- unsigned long tvm_gid, pgt_phys_addr, tvms_phys_addr; + + if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_PROMOTE_TVM)) + return -EOPNOTSUPP; @@ -392,56 +500,46 @@ index ba596b7f2240..ed7dc0fbf08b 100644 + if (!tvmc) + return -ENOMEM; + -+ for (gpr_id = 1; gpr_id < 32; gpr_id++) { -+ offset = KVM_ARCH_GUEST_ZERO + gpr_id * sizeof(unsigned long); -+ nacl_shmem_gpr_write_cove(nshmem, offset, -+ ((unsigned long *)cp)[gpr_id]); -+ } -+ kvm_arch_vcpu_load(vcpu, smp_processor_id()); -+ rc = sbi_covh_tsm_promote_to_tvm(fdt_address, tap_addr, cp->sepc, &tvm_gid); -+ if (rc) -+ goto done; -+ + INIT_LIST_HEAD(&tvmc->measured_pages); + INIT_LIST_HEAD(&tvmc->zero_pages); + INIT_LIST_HEAD(&tvmc->shared_pages); + INIT_LIST_HEAD(&tvmc->reclaim_pending_pages); + -+ tvmc->tvm_guest_id = tvm_gid; + tvmc->kvm = kvm; + kvm->arch.tvmc = tvmc; -+ -+ kvm_for_each_vcpu(target_vcpuid, target_vcpu, kvm) { -+ rc = kvm_riscv_cove_vcpu_init(target_vcpu); -+ if (rc) -+ goto vcpus_allocated; -+ -+ target_vcpu->requests = 0; -+ } -+ -+ tvmc->finalized_done = true; -+ kvm_info("Guest VM creation successful with guest id %lx\n", tvm_gid); ++ kvm->arch.vm_type = KVM_VM_TYPE_RISCV_COVE_SINGLE_STEP_INIT; + return 0; -+ -+vcpus_allocated: -+ kvm_for_each_vcpu(target_vcpuid, target_vcpu, kvm) -+ if (target_vcpu->arch.tc) -+ kfree(target_vcpu->arch.tc); -+ -+done: -+ kfree(tvmc); -+ return rc; +} + - int kvm_riscv_cove_init(void) - { - int rc; ++int kvm_riscv_cove_vm_multi_step_init(struct kvm *kvm) ++{ + unsigned long gstage_pgd_size = kvm_riscv_gstage_pgd_size(); ++ unsigned long tvm_gid, pgt_phys_addr, tvms_phys_addr; ++ struct kvm_cove_tvm_context *tvmc; ++ struct page *tvms_page, *pgt_page; + int rc = 0; + ++ // Multi-step TVM creation requires TSM that supports dynamic page conversion ++ if (!kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_MEMORY_ALLOCATION)) ++ return -EOPNOTSUPP; ++ + tvmc = kzalloc(sizeof(*tvmc), GFP_KERNEL); + if (!tvmc) + return -ENOMEM; +@@ -955,6 +1032,7 @@ int kvm_riscv_cove_vm_init(struct kvm *kvm) + goto tvm_init_failed; + + tvmc->kvm = kvm; ++ kvm->arch.vm_type = KVM_VM_TYPE_RISCV_COVE_MULTI_STEP_INIT; + kvm_info("Guest VM creation successful with guest id %lx\n", tvm_gid); + + return 0; diff --git a/arch/riscv/kvm/cove_sbi.c b/arch/riscv/kvm/cove_sbi.c -index 4759b4920226..2325ee0f2a15 100644 +index 4759b4920226..fe6050d356c3 100644 --- a/arch/riscv/kvm/cove_sbi.c +++ b/arch/riscv/kvm/cove_sbi.c -@@ -488,3 +488,23 @@ int sbi_covh_tvm_remove_pages(unsigned long tvmid, - +@@ -488,3 +488,18 @@ int sbi_covh_tvm_remove_pages(unsigned long tvmid, + return 0; } + @@ -450,49 +548,156 @@ index 4759b4920226..2325ee0f2a15 100644 + unsigned long sepc, + unsigned long *tvmid) +{ -+ struct sbiret ret; -+ int rc = 0; -+ -+ ret = sbi_ecall(SBI_EXT_COVH, SBI_EXT_COVH_PROMOTE_TO_TVM, fdt_address, -+ tap_addr, sepc, 0, 0, 0); ++ struct sbiret ret = sbi_ecall(SBI_EXT_COVH, SBI_EXT_COVH_PROMOTE_TO_TVM, ++ fdt_address, tap_addr, sepc, 0, 0, 0); + if (ret.error) { -+ rc = sbi_err_map_linux_errno(ret.error); -+ goto done; ++ return sbi_err_map_linux_errno(ret.error); + } + + *tvmid = ret.value; -+done: -+ return rc; ++ return 0; +} diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c -index a05941420307..bb5562ecc97c 100644 +index a05941420307..9a9625f9c7a9 100644 --- a/arch/riscv/kvm/main.c +++ b/arch/riscv/kvm/main.c @@ -31,12 +31,11 @@ int kvm_arch_hardware_enable(void) return rc; - + /* - * We just need to invoke aia enable for CoVE if host is in VS mode - * However, if the host is running in HS mode, we need to initialize - * other CSRs as well for legacy VMs. - * TODO: Handle host in HS mode use case. + * We just need to invoke aia enable for CoVE if host is in VS mode and TSM -+ * supports AIA (COVI extension). However, if the host is running in HS -+ * mode, we need to initialize other CSRs as well for legacy VMs. ++ * supports AIA (COVI extension). However, if the host is running in HS mode, ++ * we need to initialize other CSRs as well for legacy VMs. */ - if (unlikely(kvm_riscv_cove_enabled())) + if (unlikely(kvm_riscv_cove_enabled()) && kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_AIA)) goto enable_aia; - + hedeleg = 0; +diff --git a/arch/riscv/kvm/mmu.c b/arch/riscv/kvm/mmu.c +index 63889d910b11..baf1889dc95a 100644 +--- a/arch/riscv/kvm/mmu.c ++++ b/arch/riscv/kvm/mmu.c +@@ -359,7 +359,7 @@ int kvm_riscv_gstage_ioremap(struct kvm *kvm, gpa_t gpa, + .gfp_zero = __GFP_ZERO, + }; + +- if (is_cove_vm(kvm)) { ++ if (is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) { + kvm_debug("%s: KVM doesn't support ioremap for TVM io regions\n", __func__); + return -EPERM; + } +@@ -394,7 +394,7 @@ int kvm_riscv_gstage_ioremap(struct kvm *kvm, gpa_t gpa, + void kvm_riscv_gstage_iounmap(struct kvm *kvm, gpa_t gpa, unsigned long size) + { + /* KVM doesn't map any IO region in gstage for TVM */ +- if (is_cove_vm(kvm)) ++ if (is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return; + + spin_lock(&kvm->mmu_lock); +@@ -444,7 +444,7 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, + phys_addr_t size = slot->npages << PAGE_SHIFT; + + /* No need to unmap gstage as it is managed by TSM */ +- if (is_cove_vm(kvm)) ++ if (is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return; + + spin_lock(&kvm->mmu_lock); +@@ -458,7 +458,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, + enum kvm_mr_change change) + { + /* We don't support dirty logging for CoVE guests yet */ +- if (is_cove_vm(kvm)) ++ if (is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return; + /* + * At this point memslot has been committed and there is an +@@ -499,7 +499,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + + mmap_read_lock(current->mm); + +- if (is_cove_vm(kvm)) { ++ if (is_cove_vm_multi_step_initializing(kvm)) { + ret = kvm_riscv_cove_vm_add_memreg(kvm, base_gpa, size); + if (ret) + return ret; +@@ -571,7 +571,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + + bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) + { +- if (!kvm->arch.pgd || is_cove_vm(kvm)) ++ if (!kvm->arch.pgd || is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return false; + + gstage_unmap_range(kvm, range->start << PAGE_SHIFT, +@@ -585,7 +585,7 @@ bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range) + int ret; + kvm_pfn_t pfn = pte_pfn(range->pte); + +- if (!kvm->arch.pgd || is_cove_vm(kvm)) ++ if (!kvm->arch.pgd || is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return false; + + WARN_ON(range->end - range->start != 1); +@@ -606,7 +606,7 @@ bool kvm_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) + u32 ptep_level = 0; + u64 size = (range->end - range->start) << PAGE_SHIFT; + +- if (!kvm->arch.pgd || is_cove_vm(kvm)) ++ if (!kvm->arch.pgd || is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return false; + + WARN_ON(size != PAGE_SIZE && size != PMD_SIZE && size != PUD_SIZE); +@@ -624,7 +624,7 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) + u32 ptep_level = 0; + u64 size = (range->end - range->start) << PAGE_SHIFT; + +- if (!kvm->arch.pgd || is_cove_vm(kvm)) ++ if (!kvm->arch.pgd || is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return false; + + WARN_ON(size != PAGE_SIZE && size != PMD_SIZE && size != PUD_SIZE); +@@ -762,7 +762,7 @@ void kvm_riscv_gstage_free_pgd(struct kvm *kvm) + void *pgd = NULL; + + /* PGD is mapped in TSM */ +- if (is_cove_vm(kvm)) ++ if (is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return; + + spin_lock(&kvm->mmu_lock); +@@ -784,7 +784,7 @@ void kvm_riscv_gstage_update_hgatp(struct kvm_vcpu *vcpu) + struct kvm_arch *k = &vcpu->kvm->arch; + + /* COVE VCPU hgatp is managed by TSM. */ +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + return; + + hgatp |= (READ_ONCE(k->vmid.vmid) << HGATP_VMID_SHIFT) & HGATP_VMID; diff --git a/arch/riscv/kvm/tlb.c b/arch/riscv/kvm/tlb.c -index b007c027baed..5a3ef6ea01e9 100644 +index b007c027baed..017191116ddf 100644 --- a/arch/riscv/kvm/tlb.c +++ b/arch/riscv/kvm/tlb.c +@@ -169,7 +169,7 @@ void kvm_riscv_local_tlb_sanitize(struct kvm_vcpu *vcpu) + { + unsigned long vmid; + +- if (is_cove_vcpu(vcpu) || !kvm_riscv_gstage_vmid_bits() || ++ if (is_cove_vm_finalized(vcpu->kvm) || !kvm_riscv_gstage_vmid_bits() || + vcpu->arch.last_exit_cpu == vcpu->cpu) + return; + @@ -199,7 +199,7 @@ void kvm_riscv_hfence_gvma_vmid_all_process(struct kvm_vcpu *vcpu) struct kvm_vmid *v = &vcpu->kvm->arch.vmid; unsigned long vmid = READ_ONCE(v->vmid); - + - if (kvm_riscv_nacl_available()) + if (kvm_riscv_nacl_sync_hfence_available()) nacl_shmem_hfence_gvma_vmid_all(nacl_shmem(), vmid); @@ -501,7 +706,7 @@ index b007c027baed..5a3ef6ea01e9 100644 @@ -210,7 +210,7 @@ void kvm_riscv_hfence_vvma_all_process(struct kvm_vcpu *vcpu) struct kvm_vmid *v = &vcpu->kvm->arch.vmid; unsigned long vmid = READ_ONCE(v->vmid); - + - if (kvm_riscv_nacl_available()) + if (kvm_riscv_nacl_sync_hfence_available()) nacl_shmem_hfence_vvma_all(nacl_shmem(), vmid); @@ -544,42 +749,82 @@ index b007c027baed..5a3ef6ea01e9 100644 d.addr, d.size, d.order); else diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c -index 005c7c93536d..62153d6ca579 100644 +index 005c7c93536d..cebed69ada29 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c -@@ -730,8 +730,8 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp, - +@@ -234,7 +234,14 @@ void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) + * Keep all vcpus with non-zero id in power-off state so that + * they can be brought up using SBI HSM extension. + */ +- if (vcpu->vcpu_idx != 0) ++ if (vcpu->vcpu_idx == 0) { ++ /* ++ * The single-step CoVE guest creation process requires that ++ * all TVM pages are present in the main memory during promotion. ++ */ ++ if (unlikely(is_cove_vm_single_step_initializing(vcpu->kvm))) ++ kvm_riscv_cove_gstage_preload(vcpu); ++ } else + kvm_riscv_vcpu_power_off(vcpu); + } + +@@ -730,8 +737,8 @@ long kvm_arch_vcpu_async_ioctl(struct file *filp, + if (ioctl == KVM_INTERRUPT) { struct kvm_interrupt irq; - /* We do not support user space emulated IRQCHIP for TVMs yet */ - if (is_cove_vcpu(vcpu)) + /* We do not support user space emulated IRQCHIP for TVMs that utilize AIA yet */ -+ if (is_cove_vcpu(vcpu) && kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_AIA)) ++ if (is_cove_vm_finalized(vcpu->kvm) && kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_AIA)) return -ENXIO; - + if (copy_from_user(&irq, argp, sizeof(irq))) -@@ -997,7 +997,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) +@@ -992,12 +999,12 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) + u64 henvcfg = kvm_riscv_vcpu_get_henvcfg(vcpu->arch.isa); + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + kvm_riscv_cove_vcpu_load(vcpu); goto skip_load; } - + - if (kvm_riscv_nacl_sync_csr_available()) { + if (unlikely(kvm_riscv_cove_enabled()) || kvm_riscv_nacl_sync_csr_available()) { nshmem = nacl_shmem(); nacl_shmem_csr_write(nshmem, CSR_VSSTATUS, csr->vsstatus); nacl_shmem_csr_write(nshmem, CSR_VSIE, csr->vsie); -@@ -1061,7 +1061,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) - +@@ -1048,7 +1055,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) + + vcpu->cpu = -1; + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm) || is_cove_vm_multi_step_initializing(vcpu->kvm)) { + kvm_riscv_cove_vcpu_put(vcpu); + return; + } +@@ -1061,7 +1068,7 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) + kvm_riscv_vcpu_timer_save(vcpu); - + - if (kvm_riscv_nacl_available()) { + if (kvm_riscv_nacl_sync_csr_available()) { /** * For TVMs, we don't need a separate case as TSM only updates * the required CSRs during the world switch. All other CSR -@@ -1325,8 +1325,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) +@@ -1114,7 +1121,7 @@ static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu) + if (kvm_check_request(KVM_REQ_VCPU_RESET, vcpu)) + kvm_riscv_reset_vcpu(vcpu); + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + /* + * KVM doesn't need to do anything special here + * as the TSM is expected track the tlb version and issue +@@ -1325,8 +1332,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) */ kvm_riscv_vcpu_flush_interrupts(vcpu); - + - /* Update HVIP CSR for current CPU only for non TVMs */ - if (!is_cove_vcpu(vcpu)) + /* @@ -588,8 +833,183 @@ index 005c7c93536d..62153d6ca579 100644 + */ + if (!is_cove_vcpu(vcpu) || !kvm_riscv_cove_capability(KVM_COVE_TSM_CAP_AIA)) kvm_riscv_update_hvip(vcpu); - + if (ret <= 0 || +diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c +index 51eb43425419..b91328399254 100644 +--- a/arch/riscv/kvm/vcpu_exit.c ++++ b/arch/riscv/kvm/vcpu_exit.c +@@ -41,7 +41,7 @@ static int gstage_page_fault(struct kvm_vcpu *vcpu, struct kvm_run *run, + }; + } + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + /* CoVE doesn't care about PTE prots now. No need to compute the prots */ + ret = kvm_riscv_cove_handle_pagefault(vcpu, fault_addr, hva); + } else { +@@ -143,7 +143,7 @@ void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, + { + unsigned long vsstatus; + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + kvm_err("RISC-V KVM do not support redirect to CoVE guest yet\n"); + return; + } +@@ -213,13 +213,13 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, + ret = gstage_page_fault(vcpu, run, trap); + break; + case EXC_SUPERVISOR_SYSCALL: +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + ret = kvm_riscv_cove_vcpu_sbi_ecall(vcpu, run); + else if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) + ret = kvm_riscv_vcpu_sbi_ecall(vcpu, run); + break; + case EXC_CUSTOM_KVM_COVE_RUN_FAIL: +- if (likely(is_cove_vcpu(vcpu))) { ++ if (likely(is_cove_vm_finalized(vcpu->kvm))) { + ret = -EACCES; + run->fail_entry.hardware_entry_failure_reason = + KVM_EXIT_FAIL_ENTRY_COVE_RUN_VCPU; +diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c +index 56eeb864a7f6..cd3366bd1d87 100644 +--- a/arch/riscv/kvm/vcpu_insn.c ++++ b/arch/riscv/kvm/vcpu_insn.c +@@ -162,7 +162,7 @@ static int truly_illegal_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_cpu_trap utrap = { 0 }; + + /* The host can not redirect any illegal instruction trap to TVM */ +- if (unlikely(is_cove_vcpu(vcpu))) ++ if (unlikely(is_cove_vm_finalized(vcpu->kvm))) + return -EPERM; + + /* Redirect trap to Guest VCPU */ +@@ -182,7 +182,7 @@ static int truly_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_cpu_trap utrap = { 0 }; + + /* The host can not redirect any virtual instruction trap to TVM */ +- if (unlikely(is_cove_vcpu(vcpu))) ++ if (unlikely(is_cove_vm_finalized(vcpu->kvm))) + return -EPERM; + + /* Redirect trap to Guest VCPU */ +@@ -434,7 +434,7 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, + if (insn == 0) { + ct = &vcpu->arch.guest_context; + +- if (unlikely(is_cove_vcpu(vcpu))) ++ if (unlikely(is_cove_vm_finalized(vcpu->kvm))) + return -EPERM; + + insn = kvm_riscv_vcpu_unpriv_read(vcpu, true, +@@ -489,7 +489,7 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = htinst | INSN_16BIT_MASK; + insn_len = (htinst & BIT(1)) ? INSN_LEN(insn) : 2; + } else { +- if (unlikely(is_cove_vcpu(vcpu))) ++ if (unlikely(is_cove_vm_finalized(vcpu->kvm))) + return -EFAULT; + /* + * Bit[0] == 0 implies trapped instruction value is +@@ -618,7 +618,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn = htinst | INSN_16BIT_MASK; + insn_len = (htinst & BIT(1)) ? INSN_LEN(insn) : 2; + } else { +- if (unlikely(is_cove_vcpu(vcpu))) ++ if (unlikely(is_cove_vm_finalized(vcpu->kvm))) + return -EFAULT; + /* + * Bit[0] == 0 implies trapped instruction value is +@@ -635,7 +635,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + insn_len = INSN_LEN(insn); + } + +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + nshmem = nacl_shmem(); + data = nacl_shmem_gpr_read_cove(nshmem, + REG_INDEX(insn, SH_RS2) * 8 + +@@ -659,7 +659,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + #ifdef CONFIG_64BIT + } else if ((insn & INSN_MASK_C_SD) == INSN_MATCH_C_SD) { + len = 8; +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + data64 = nacl_shmem_gpr_read_cove( + nshmem, + RVC_RS2S(insn) * 8 + KVM_ARCH_GUEST_ZERO); +@@ -669,7 +669,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + } else if ((insn & INSN_MASK_C_SDSP) == INSN_MATCH_C_SDSP && + ((insn >> SH_RD) & 0x1f)) { + len = 8; +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + data64 = nacl_shmem_gpr_read_cove( + nshmem, REG_INDEX(insn, SH_RS2C) * 8 + + KVM_ARCH_GUEST_ZERO); +@@ -679,7 +679,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + #endif + } else if ((insn & INSN_MASK_C_SW) == INSN_MATCH_C_SW) { + len = 4; +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + data32 = nacl_shmem_gpr_read_cove( + nshmem, + RVC_RS2S(insn) * 8 + KVM_ARCH_GUEST_ZERO); +@@ -689,7 +689,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, + } else if ((insn & INSN_MASK_C_SWSP) == INSN_MATCH_C_SWSP && + ((insn >> SH_RD) & 0x1f)) { + len = 4; +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + data32 = nacl_shmem_gpr_read_cove( + nshmem, REG_INDEX(insn, SH_RS2C) * 8 + + KVM_ARCH_GUEST_ZERO); +@@ -779,13 +779,13 @@ int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) + len = vcpu->arch.mmio_decode.len; + shift = vcpu->arch.mmio_decode.shift; + +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + nshmem = nacl_shmem(); + + switch (len) { + case 1: + data8 = *((u8 *)run->mmio.data); +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + nacl_shmem_gpr_write_cove(nshmem, + REG_INDEX(insn, SH_RD) * 8 + + KVM_ARCH_GUEST_ZERO, +@@ -797,7 +797,7 @@ int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) + break; + case 2: + data16 = *((u16 *)run->mmio.data); +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + nacl_shmem_gpr_write_cove(nshmem, + REG_INDEX(insn, SH_RD) * 8 + + KVM_ARCH_GUEST_ZERO, +@@ -809,7 +809,7 @@ int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) + break; + case 4: + data32 = *((u32 *)run->mmio.data); +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + nacl_shmem_gpr_write_cove(nshmem, + REG_INDEX(insn, SH_RD) * 8 + + KVM_ARCH_GUEST_ZERO, +@@ -821,7 +821,7 @@ int kvm_riscv_vcpu_mmio_return(struct kvm_vcpu *vcpu, struct kvm_run *run) + break; + case 8: + data64 = *((u64 *)run->mmio.data); +- if (is_cove_vcpu(vcpu)) { ++ if (is_cove_vm_finalized(vcpu->kvm)) { + nacl_shmem_gpr_write_cove(nshmem, + REG_INDEX(insn, SH_RD) * 8 + + KVM_ARCH_GUEST_ZERO, diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 8bc7d7398349..9399cf5a3062 100644 --- a/arch/riscv/kvm/vcpu_sbi.c @@ -604,7 +1024,7 @@ index 8bc7d7398349..9399cf5a3062 100644 + .handler = NULL, +}; #endif - + struct kvm_riscv_sbi_extension_entry { @@ -96,6 +101,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = { .dis_idx = KVM_RISCV_SBI_EXT_COVG, @@ -615,7 +1035,7 @@ index 8bc7d7398349..9399cf5a3062 100644 + .ext_ptr = &vcpu_sbi_ext_covh, + }, }; - + void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/riscv/kvm/vcpu_sbi_covg.c b/arch/riscv/kvm/vcpu_sbi_covg.c index 44a3b06d0593..42f3571361a0 100644 @@ -623,7 +1043,7 @@ index 44a3b06d0593..42f3571361a0 100644 +++ b/arch/riscv/kvm/vcpu_sbi_covg.c @@ -55,7 +55,7 @@ static int cove_share_converted_page(struct kvm_vcpu *vcpu, gpa_t gpa, } - + static int cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, - unsigned long *sbi_err) + struct kvm_vcpu_sbi_return *retdata) @@ -631,25 +1051,25 @@ index 44a3b06d0593..42f3571361a0 100644 unsigned long hva = gfn_to_hva(vcpu->kvm, gpa >> PAGE_SHIFT); struct kvm_cove_tvm_context *tvmc = vcpu->kvm->arch.tvmc; @@ -66,7 +66,7 @@ static int cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, - + if (kvm_is_error_hva(hva)) { /* Address is out of the guest ram memory region. */ - *sbi_err = SBI_ERR_INVALID_PARAM; + retdata->err_val = SBI_ERR_INVALID_PARAM; return 0; } - + @@ -95,6 +95,7 @@ static int cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, list_add(&tpage->link, &tvmc->shared_pages); spin_unlock(&vcpu->kvm->mmu_lock); - + + retdata->out_val = page_to_phys(tpage->page); return 0; - + free_tpage: @@ -104,7 +105,7 @@ static int cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, } - + static int kvm_riscv_cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, - unsigned long *sbi_err) + struct kvm_vcpu_sbi_return *retdata) @@ -659,11 +1079,11 @@ index 44a3b06d0593..42f3571361a0 100644 @@ -129,7 +130,7 @@ static int kvm_riscv_cove_share_page(struct kvm_vcpu *vcpu, gpa_t gpa, if (converted) return cove_share_converted_page(vcpu, gpa, tpage); - + - return cove_share_page(vcpu, gpa, sbi_err); + return cove_share_page(vcpu, gpa, retdata); } - + static int kvm_riscv_cove_unshare_page(struct kvm_vcpu *vcpu, gpa_t gpa) @@ -189,7 +190,7 @@ static int kvm_sbi_ext_covg_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, case SBI_EXT_COVG_SHARE_MEMORY: @@ -676,10 +1096,10 @@ index 44a3b06d0593..42f3571361a0 100644 } diff --git a/arch/riscv/kvm/vcpu_sbi_covh.c b/arch/riscv/kvm/vcpu_sbi_covh.c new file mode 100644 -index 000000000000..ef3e255732b4 +index 000000000000..d6362e9e3b48 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_covh.c -@@ -0,0 +1,84 @@ +@@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 IBM. @@ -687,56 +1107,58 @@ index 000000000000..ef3e255732b4 + * Authors: + * Wojciech Ozga + */ -+ +#include +#include +#include -+#include -+#include -+#include -+#include +#include -+#include +#include -+#include +#include -+#include -+#include -+ -+static int preload_pages(struct kvm_vcpu *vcpu) { -+ unsigned long hva, fault_addr, page; -+ struct kvm_memory_slot *memslot; -+ bool writable; -+ int bkt; -+ -+ kvm_for_each_memslot(memslot, bkt, kvm_memslots(vcpu->kvm)) { -+ for (page = 0; page < memslot->npages; page++) { -+ fault_addr = gfn_to_gpa(memslot->base_gfn) + -+ page * PAGE_SIZE; -+ hva = gfn_to_hva_memslot_prot(memslot, -+ gpa_to_gfn(fault_addr), -+ &writable); -+ if (!kvm_is_error_hva(hva)) -+ kvm_riscv_gstage_map(vcpu, memslot, fault_addr, -+ hva, NULL); -+ } -+ } -+ -+ return 0; -+} ++#include + +static int kvm_riscv_cove_promote_to_tvm(struct kvm_vcpu *vcpu, + unsigned long fdt_address, + unsigned long tap_addr) { -+ int rc; ++ struct kvm_cove_tvm_context *tvmc; ++ struct kvm_cpu_context *cntx; ++ struct kvm_vcpu *target_vcpu; ++ unsigned long target_vcpuid; ++ void *nshmem = nacl_shmem(); ++ int rc, gpr_id, offset; + -+ preload_pages(vcpu); -+ rc = kvm_riscv_cove_vm_single_step_init(vcpu, fdt_address, tap_addr); ++ rc = kvm_riscv_cove_vm_single_step_init(vcpu->kvm); + if (rc) -+ goto done; ++ goto exit; ++ ++ tvmc = vcpu->kvm->arch.tvmc; ++ cntx = &vcpu->arch.guest_context; ++ ++ /* Reset all but boot vcpu and preload VM's pages */ ++ kvm_for_each_vcpu(target_vcpuid, target_vcpu, vcpu->kvm) { ++ kvm_arch_vcpu_postcreate(target_vcpu); ++ target_vcpu->requests = 0; ++ } + -+ vcpu->kvm->arch.vm_type = KVM_VM_TYPE_RISCV_COVE; -+done: ++ for (gpr_id = 1; gpr_id < 32; gpr_id++) { ++ offset = KVM_ARCH_GUEST_ZERO + gpr_id * sizeof(unsigned long); ++ nacl_shmem_gpr_write_cove(nshmem, offset, ++ ((unsigned long *)cntx)[gpr_id]); ++ } ++ kvm_arch_vcpu_load(vcpu, smp_processor_id()); ++ rc = sbi_covh_tsm_promote_to_tvm(fdt_address, tap_addr, cntx->sepc+4, ++ &tvmc->tvm_guest_id); ++ if (rc) ++ goto vcpus_allocated; ++ ++ tvmc->finalized_done = true; ++ kvm_info("CoVE Guest creation successful with guest id %lx\n", tvmc->tvm_guest_id); ++ return 0; ++ ++vcpus_allocated: ++ kvm_for_each_vcpu(target_vcpuid, target_vcpu, vcpu->kvm) ++ kvm_riscv_cove_vcpu_destroy(vcpu); ++ kvm_riscv_cove_vm_destroy(vcpu->kvm); ++ ++exit: + return rc; +} + @@ -745,12 +1167,12 @@ index 000000000000..ef3e255732b4 +{ + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long funcid = cp->a6; -+ int ret; ++ int ret; + + switch (funcid) { + case SBI_EXT_COVH_PROMOTE_TO_TVM: + ret = kvm_riscv_cove_promote_to_tvm(vcpu, cp->a0, cp->a1); -+ return 0; ++ return ret; + + default: + kvm_err("%s: Unsupported guest SBI %ld.\n", __func__, funcid); @@ -764,45 +1186,135 @@ index 000000000000..ef3e255732b4 + .extid_end = SBI_EXT_COVH, + .handler = kvm_sbi_ext_covh_handler, +}; +diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c +index f059e148c680..b654eaa53c71 100644 +--- a/arch/riscv/kvm/vcpu_timer.c ++++ b/arch/riscv/kvm/vcpu_timer.c +@@ -73,7 +73,7 @@ static int kvm_riscv_vcpu_timer_cancel(struct kvm_vcpu_timer *t) + static int kvm_riscv_vcpu_update_vstimecmp(struct kvm_vcpu *vcpu, u64 ncycles) + { + /* Host is not allowed to update the vstimecmp for the TVM */ +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + return 0; + + #if defined(CONFIG_32BIT) +@@ -229,7 +229,7 @@ int kvm_riscv_vcpu_set_reg_timer(struct kvm_vcpu *vcpu, + /* For trusted VMs we can not update htimedelta. We can just + * read it from shared memory. + */ +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + return -EOPNOTSUPP; + gt->time_delta = reg_val - get_cycles64(); + break; +@@ -311,7 +311,7 @@ void kvm_riscv_vcpu_timer_restore(struct kvm_vcpu *vcpu) + struct kvm_vcpu_timer *t = &vcpu->arch.timer; + + /* While in CoVE, HOST must not manage HTIMEDELTA or VSTIMECMP for TVM */ +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm)) + goto skip_hcsr_update; + + kvm_riscv_vcpu_update_timedelta(vcpu); +@@ -374,7 +374,7 @@ void kvm_riscv_guest_timer_init(struct kvm *kvm) + struct kvm_guest_timer *gt = &kvm->arch.timer; + + riscv_cs_get_mult_shift(>->nsec_mult, >->nsec_shift); +- if (is_cove_vm(kvm)) { ++ if (is_cove_vm_finalized(kvm)) { + /* For TVMs htimedelta is managed by TSM and it's communicated using + * NACL shmem interface when first time VCPU is run. so we read it in + * kvm_riscv_cove_vcpu_switchto() where we enter VCPUs. diff --git a/arch/riscv/kvm/vm.c b/arch/riscv/kvm/vm.c -index 8a1460dba76c..6df73ea8e16f 100644 +index 8a1460dba76c..af7dc301e0b6 100644 --- a/arch/riscv/kvm/vm.c +++ b/arch/riscv/kvm/vm.c -@@ -44,15 +44,15 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) - - if (unlikely(type == KVM_VM_TYPE_RISCV_COVE)) { +@@ -42,17 +42,22 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) + return r; + } + +- if (unlikely(type == KVM_VM_TYPE_RISCV_COVE)) { ++ if (unlikely(type == KVM_VM_TYPE_RISCV_COVE_MULTI_STEP_INIT)) { if (!kvm_riscv_cove_enabled()) { - kvm_err("Unable to init CoVE VM because cove is not enabled\n"); + kvm_err("Unable to init CoVE VM because CoVE extension is not enabled\n"); return -EPERM; } - +- - r = kvm_riscv_cove_vm_init(kvm); + r = kvm_riscv_cove_vm_multi_step_init(kvm); ++ if (r) ++ return r; ++ } else if (unlikely(type == KVM_VM_TYPE_RISCV_COVE_SINGLE_STEP_INIT)) { ++ if (!kvm_riscv_cove_enabled()) { ++ kvm_err("Unable to init CoVE VM because CoVE extension is not enabled\n"); ++ return -EPERM; ++ } ++ r = kvm_riscv_cove_vm_single_step_init(kvm); if (r) return r; - kvm->arch.vm_type = type; +- kvm->arch.vm_type = type; - kvm_info("Trusted VM instance init successful\n"); -+ kvm_info("CoVE VM instance init successful\n"); } - + kvm_riscv_aia_init_vm(kvm); +@@ -68,7 +73,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) + + kvm_riscv_aia_destroy_vm(kvm); + +- if (unlikely(is_cove_vm(kvm))) ++ if (unlikely(is_cove_vm_finalized(kvm)) || unlikely(is_cove_vm_multi_step_initializing(kvm))) + kvm_riscv_cove_vm_destroy(kvm); + } + +@@ -232,8 +237,6 @@ long kvm_arch_vm_ioctl(struct file *filp, + + switch (ioctl) { + case KVM_RISCV_COVE_MEASURE_REGION: +- if (!is_cove_vm(kvm)) +- return -EINVAL; + if (copy_from_user(&mr, argp, sizeof(mr))) + return -EFAULT; + +diff --git a/arch/riscv/kvm/vmid.c b/arch/riscv/kvm/vmid.c +index dc03601a6e4c..6f5a293235bb 100644 +--- a/arch/riscv/kvm/vmid.c ++++ b/arch/riscv/kvm/vmid.c +@@ -58,7 +58,7 @@ int kvm_riscv_gstage_vmid_init(struct kvm *kvm) + bool kvm_riscv_gstage_vmid_ver_changed(struct kvm *kvm) + { + /* VMID version can't be changed by the host for TVMs */ +- if (!vmid_bits || is_cove_vm(kvm)) ++ if (!vmid_bits || is_cove_vm_finalized(kvm) || is_cove_vm_multi_step_initializing(kvm)) + return false; + + return unlikely(READ_ONCE(kvm->arch.vmid.vmid_version) != +@@ -78,7 +78,7 @@ void kvm_riscv_gstage_vmid_update(struct kvm_vcpu *vcpu) + struct kvm_vmid *vmid = &vcpu->kvm->arch.vmid; + + /* No VMID management for TVMs by the host */ +- if (is_cove_vcpu(vcpu)) ++ if (is_cove_vm_finalized(vcpu->kvm) || is_cove_vm_multi_step_initializing(vcpu->kvm)) + return; + + if (!kvm_riscv_gstage_vmid_ver_changed(kvm)) diff --git a/arch/riscv/mm/mem_encrypt.c b/arch/riscv/mm/mem_encrypt.c -index 8523c508c3a5..498fbf5c6c9b 100644 +index 8523c508c3a5..8619444538a3 100644 --- a/arch/riscv/mm/mem_encrypt.c +++ b/arch/riscv/mm/mem_encrypt.c -@@ -25,25 +25,44 @@ bool force_dma_unencrypted(struct device *dev) - +@@ -25,25 +25,42 @@ bool force_dma_unencrypted(struct device *dev) + int set_memory_encrypted(unsigned long addr, int numpages) { + int i, rc; + if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT)) return 0; - + if (!PAGE_ALIGNED(addr)) return -EINVAL; - + - return sbi_covg_unshare_memory(__pa(addr), numpages * PAGE_SIZE); + rc = sbi_covg_unshare_memory(__pa(addr), numpages * PAGE_SIZE); + if (rc) { @@ -810,21 +1322,20 @@ index 8523c508c3a5..498fbf5c6c9b 100644 + for (i = 0; i < numpages && rc == 0; i++) + rc = sbi_covg_unshare_memory(__pa(addr + i * PAGE_SIZE), PAGE_SIZE); + } -+ + return rc; } EXPORT_SYMBOL_GPL(set_memory_encrypted); - + int set_memory_decrypted(unsigned long addr, int numpages) { + int i, rc; + if (!cc_platform_has(CC_ATTR_MEM_ENCRYPT)) return 0; - + if (!PAGE_ALIGNED(addr)) return -EINVAL; - + - return sbi_covg_share_memory(__pa(addr), numpages * PAGE_SIZE); + rc = sbi_covg_share_memory(__pa(addr), numpages * PAGE_SIZE); + if (rc) { @@ -833,11 +1344,10 @@ index 8523c508c3a5..498fbf5c6c9b 100644 + for (i = 0; i < numpages && rc == 0; i++) + rc = sbi_covg_share_memory(__pa(addr + i * PAGE_SIZE), PAGE_SIZE); + } -+ + return rc; } EXPORT_SYMBOL_GPL(set_memory_decrypted); - + diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index d1a68b6d03b3..46e2ce22c729 100644 --- a/drivers/of/fdt.c @@ -845,7 +1355,7 @@ index d1a68b6d03b3..46e2ce22c729 100644 @@ -1167,6 +1167,7 @@ int __init early_init_dt_scan_chosen(char *cmdline) early_init_dt_check_for_initrd(node); early_init_dt_check_for_elfcorehdr(node); - + +#ifndef CONFIG_RISCV_COVE_GUEST rng_seed = of_get_flat_dt_prop(node, "rng-seed", &l); if (rng_seed && l > 0) { @@ -855,6 +1365,21 @@ index d1a68b6d03b3..46e2ce22c729 100644 fdt_totalsize(initial_boot_params)); } +#endif - + /* Retrieve command line */ - p = of_get_flat_dt_prop(node, "bootargs", &l); \ No newline at end of file + p = of_get_flat_dt_prop(node, "bootargs", &l); +diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h +index 84a73b54f7cf..45126d1f36cd 100644 +--- a/include/uapi/linux/kvm.h ++++ b/include/uapi/linux/kvm.h +@@ -919,7 +919,9 @@ struct kvm_ppc_resize_hpt { + * RISCV-V Confidential VM type. The large bit shift is chosen on purpose + * to allow other architectures to have their specific VM types if required. + */ +-#define KVM_VM_TYPE_RISCV_COVE (1UL << 9) ++#define KVM_VM_TYPE_RISCV_COVE_MULTI_STEP_INIT (1UL << 9) ++#define KVM_VM_TYPE_RISCV_COVE_SINGLE_STEP_INIT (1UL << 10) ++ + /* + * ioctls for /dev/kvm fds: + */ diff --git a/security-monitor/Cargo.lock b/security-monitor/Cargo.lock new file mode 100644 index 00000000..a5ba7d12 --- /dev/null +++ b/security-monitor/Cargo.lock @@ -0,0 +1,861 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bindgen" +version = "0.60.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062dddbc1ba4aca46de6338e2bf87771414c335f7b2f2036e8f3e9befebf88e6" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "clap", + "env_logger", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "which", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap", + "strsim", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type-rs" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6419a5c75e40011b9fe0174db3fe24006ab122fbe1b7e9cc5974b338a755c76" + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fdt-rs" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581d3afdd654deb68c19fcbe4bc411910cc64067d4a13d8637bda7722cb9c2ea" +dependencies = [ + "endian-type-rs", + "fallible-iterator", + "memoffset 0.5.6", + "num-derive", + "num-traits", + "rustc_version", + "static_assertions", + "unsafe_unwrap", +] + +[[package]] +name = "flattened_device_tree" +version = "0.1.0" +dependencies = [ + "fdt-rs", + "thiserror-no-std", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.167" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" + +[[package]] +name = "libloading" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +dependencies = [ + "cfg-if", + "windows-targets", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "opensbi-sys" +version = "0.1.0" +dependencies = [ + "bindgen", +] + +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pointers_utility" +version = "0.1.0" +dependencies = [ + "thiserror-no-std", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "riscv-decode" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8b4cfb0da0528321d22daee4299a23a8c5ac8848623d716e898d2a9eec0694" + +[[package]] +name = "riscv_cove_tap" +version = "0.1.0" +dependencies = [ + "aes-gcm", + "thiserror-no-std", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "security-monitor" +version = "0.3.0" +dependencies = [ + "flattened_device_tree", + "memoffset 0.9.1", + "opensbi-sys", + "pointers_utility", + "riscv-decode", + "riscv_cove_tap", + "sha2", + "spin", + "thiserror-no-std", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" + +[[package]] +name = "thiserror-impl-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58e6318948b519ba6dc2b442a6d0b904ebfb8d411a3ad3e07843615a72249758" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-no-std" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3ad459d94dd517257cc96add8a43190ee620011bb6e6cdc82dafd97dfafafea" +dependencies = [ + "thiserror-impl-no-std", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "unsafe_unwrap" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1230ec65f13e0f9b28d789da20d2d419511893ea9dac2c1f4ef67b8b14e5da80" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/security-monitor/platform/generic/configs/defconfig b/security-monitor/platform/generic/configs/defconfig index 9519187d..1ce6a120 100644 --- a/security-monitor/platform/generic/configs/defconfig +++ b/security-monitor/platform/generic/configs/defconfig @@ -41,4 +41,4 @@ CONFIG_FDT_SERIAL_XILINX_UARTLITE=y CONFIG_SERIAL_SEMIHOSTING=y CONFIG_FDT_TIMER=y CONFIG_FDT_TIMER_MTIMER=y -CONFIG_FDT_TIMER_PLMT=y \ No newline at end of file +CONFIG_FDT_TIMER_PLMT=y diff --git a/security-monitor/platform/opensbi_v1.4.patch b/security-monitor/platform/opensbi_v1.4.patch index 6196a004..0b2df785 100644 --- a/security-monitor/platform/opensbi_v1.4.patch +++ b/security-monitor/platform/opensbi_v1.4.patch @@ -1,5 +1,5 @@ diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c -index 770fee0..9e08308 100644 +index a0ab0c6..8e2e838 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -369,7 +369,7 @@ static int sbi_hart_smepmp_configure(struct sbi_scratch *scratch, diff --git a/security-monitor/rust-crates/opensbi-sys/Cargo.toml b/security-monitor/rust-crates/opensbi-sys/Cargo.toml index 3a72de40..b87b484a 100644 --- a/security-monitor/rust-crates/opensbi-sys/Cargo.toml +++ b/security-monitor/rust-crates/opensbi-sys/Cargo.toml @@ -7,4 +7,4 @@ build = "build.rs" edition = "2021" [build-dependencies] -bindgen = "0.60" \ No newline at end of file +bindgen = "0.60.1" \ No newline at end of file diff --git a/security-monitor/rust-crates/opensbi.sh b/security-monitor/rust-crates/opensbi.sh index 9f6eb514..8cb430a6 100755 --- a/security-monitor/rust-crates/opensbi.sh +++ b/security-monitor/rust-crates/opensbi.sh @@ -32,7 +32,7 @@ mkdir -p ${WORK_DIR} cd ${OPENSBI_SOURCE_DIR}/ -make CROSS_COMPILE=${CROSS_COMPILE} O=${WORK_DIR} PLATFORM=generic -j$(nproc) -make CROSS_COMPILE=${CROSS_COMPILE} I=${WORK_DIR} PLATFORM=generic install -j$(nproc) +make PLATFORM_RISCV_XLEN=${PLATFORM_RISCV_XLEN} PLATFORM_RISCV_ISA=${PLATFORM_RISCV_ISA} PLATFORM_RISCV_ABI=${PLATFORM_RISCV_ABI} CROSS_COMPILE=${CROSS_COMPILE} O=${WORK_DIR} PLATFORM=generic -j$(nproc) +make PLATFORM_RISCV_XLEN=${PLATFORM_RISCV_XLEN} PLATFORM_RISCV_ISA=${PLATFORM_RISCV_ISA} PLATFORM_RISCV_ABI=${PLATFORM_RISCV_ABI} CROSS_COMPILE=${CROSS_COMPILE} I=${WORK_DIR} PLATFORM=generic install -j$(nproc) echo "export PATH=${WORK_DIR}/lib:${WORK_DIR}/bin:\${PATH}" >> ${INSTALL_DIR}/env diff --git a/security-monitor/src/core/architecture/riscv/sbi/covh_extension.rs b/security-monitor/src/core/architecture/riscv/sbi/covh_extension.rs index 6d4a008e..0bff9eb3 100644 --- a/security-monitor/src/core/architecture/riscv/sbi/covh_extension.rs +++ b/security-monitor/src/core/architecture/riscv/sbi/covh_extension.rs @@ -20,21 +20,21 @@ impl CovhExtension { pub const SBI_EXT_COVH_TSM_LOCAL_FENCE: usize = 4; pub const SBI_EXT_COVH_CREATE_TVM: usize = 5; pub const SBI_EXT_COVH_FINALIZE_TVM: usize = 6; - pub const SBI_EXT_COVH_DESTROY_TVM: usize = 7; - pub const SBI_EXT_COVH_TVM_ADD_MEMORY_REGION: usize = 8; - pub const SBI_EXT_COVH_TVM_ADD_PGT_PAGES: usize = 9; - pub const SBI_EXT_COVH_TVM_ADD_MEASURED_PAGES: usize = 10; - pub const SBI_EXT_COVH_TVM_ADD_ZERO_PAGES: usize = 11; - pub const SBI_EXT_COVH_TVM_ADD_SHARED_PAGES: usize = 12; - pub const SBI_EXT_COVH_TVM_CREATE_VCPU: usize = 13; - pub const SBI_EXT_COVH_TVM_VCPU_RUN: usize = 14; - pub const SBI_EXT_COVH_TVM_INITIATE_FENCE: usize = 15; - pub const SBI_EXT_COVH_TVM_INVALIDATE_PAGES: usize = 16; - pub const SBI_EXT_COVH_TVM_VALIDATE_PAGES: usize = 17; - pub const SBI_EXT_COVH_TVM_PROMOTE_PAGE: usize = 18; - pub const SBI_EXT_COVH_TVM_DEMOTE_PAGE: usize = 19; - pub const SBI_EXT_COVH_TVM_REMOVE_PAGES: usize = 20; - pub const SBI_EXT_COVH_PROMOTE_TO_TVM: usize = 21; + pub const SBI_EXT_COVH_PROMOTE_TO_TVM: usize = 7; + pub const SBI_EXT_COVH_DESTROY_TVM: usize = 8; + pub const SBI_EXT_COVH_TVM_ADD_MEMORY_REGION: usize = 9; + pub const SBI_EXT_COVH_TVM_ADD_PGT_PAGES: usize = 10; + pub const SBI_EXT_COVH_TVM_ADD_MEASURED_PAGES: usize = 11; + pub const SBI_EXT_COVH_TVM_ADD_ZERO_PAGES: usize = 12; + pub const SBI_EXT_COVH_TVM_ADD_SHARED_PAGES: usize = 13; + pub const SBI_EXT_COVH_TVM_CREATE_VCPU: usize = 14; + pub const SBI_EXT_COVH_TVM_VCPU_RUN: usize = 15; + pub const SBI_EXT_COVH_TVM_INITIATE_FENCE: usize = 16; + pub const SBI_EXT_COVH_TVM_INVALIDATE_PAGES: usize = 17; + pub const SBI_EXT_COVH_TVM_VALIDATE_PAGES: usize = 18; + pub const SBI_EXT_COVH_TVM_PROMOTE_PAGE: usize = 19; + pub const SBI_EXT_COVH_TVM_DEMOTE_PAGE: usize = 20; + pub const SBI_EXT_COVH_TVM_REMOVE_PAGES: usize = 21; pub fn from_function_id(function_id: usize) -> Self { match function_id { diff --git a/security-monitor/src/core/control_data/confidential_hart.rs b/security-monitor/src/core/control_data/confidential_hart.rs index 83ea109d..276ee206 100644 --- a/security-monitor/src/core/control_data/confidential_hart.rs +++ b/security-monitor/src/core/control_data/confidential_hart.rs @@ -10,6 +10,7 @@ use crate::core::architecture::{ use crate::core::control_data::confidential_hart_remote_command::ConfidentialHartRemoteCommandExecutable; use crate::core::control_data::{ConfidentialHartRemoteCommand, ConfidentialVmId, MeasurementDigest, ResumableOperation}; use crate::core::hardware_setup::HardwareSetup; +use crate::core::memory_layout::ConfidentialVmPhysicalAddress; use crate::error::Error; extern "C" { @@ -124,7 +125,9 @@ impl ConfidentialHart { } /// Constructs a confidential hart with the state of the non-confidential hart that made a call to promote the VM to confidential VM - pub fn from_vm_hart(id: usize, program_counter: usize, htimedelta: usize, shared_memory: &NaclSharedMemory) -> Self { + pub fn from_vm_hart( + id: usize, program_counter: usize, fdt_address: ConfidentialVmPhysicalAddress, htimedelta: usize, shared_memory: &NaclSharedMemory, + ) -> Self { // We first create a confidential hart in the reset state and then fill this state with the runtime state of the hart that made a // call to promote to confidential VM. This state consists of GPRs and VS-level CSRs. let mut confidential_hart = Self::from_vm_hart_reset(id, htimedelta, shared_memory); @@ -143,8 +146,8 @@ impl ConfidentialHart { confidential_hart_state.csrs_mut().vsatp.save_nacl_value_in_main_memory(&shared_memory); // Store the program counter of the VM, so that we can resume confidential VM at the point it became promoted. confidential_hart_state.csrs_mut().mepc.save_value_in_main_memory(program_counter); + confidential_hart_state.gprs_mut().write(GeneralPurposeRegister::a1, fdt_address.usize()); confidential_hart.lifecycle_state = HartLifecycleState::Started; - confidential_hart.resumable_operation = Some(ResumableOperation::SbiRequest()); confidential_hart } diff --git a/security-monitor/src/core/page_allocator/page.rs b/security-monitor/src/core/page_allocator/page.rs index b6396e2b..c4e0984d 100644 --- a/security-monitor/src/core/page_allocator/page.rs +++ b/security-monitor/src/core/page_allocator/page.rs @@ -312,11 +312,11 @@ impl Page { pub fn measure(&self, digest: &mut MeasurementDigest, guest_physical_address: usize) { use sha2::Digest; let mut hasher = DigestType::new_with_prefix(digest.clone()); - hasher.update(guest_physical_address.to_le_bytes()); // below unsafe is ok because the page has been initialized and it owns the entire memory region. // We are creating a slice of bytes, so the number of elements in the slice is the same as the size of the page. let slice: &[u8] = unsafe { core::slice::from_raw_parts(self.address().to_ptr(), self.size().in_bytes()) }; if slice.iter().find(|b| **b != 0).is_some() { + hasher.update(guest_physical_address.to_le_bytes()); hasher.update(&slice); hasher.finalize_into(digest); } diff --git a/security-monitor/src/non_confidential_flow/handlers/cove_host_extension/promote_to_confidential_vm.rs b/security-monitor/src/non_confidential_flow/handlers/cove_host_extension/promote_to_confidential_vm.rs index 21bccf66..e4b62de1 100644 --- a/security-monitor/src/non_confidential_flow/handlers/cove_host_extension/promote_to_confidential_vm.rs +++ b/security-monitor/src/non_confidential_flow/handlers/cove_host_extension/promote_to_confidential_vm.rs @@ -78,7 +78,9 @@ impl PromoteToConfidentialVm { // We create a fixed number of harts (all but the boot hart are in the reset state). let confidential_harts: Vec<_> = (0..number_of_confidential_harts) .map(|confidential_hart_id| match confidential_hart_id { - Self::BOOT_HART_ID => ConfidentialHart::from_vm_hart(confidential_hart_id, self.program_counter, htimedelta, shared_memory), + Self::BOOT_HART_ID => { + ConfidentialHart::from_vm_hart(confidential_hart_id, self.program_counter, self.fdt_address, htimedelta, shared_memory) + } _ => ConfidentialHart::from_vm_hart_reset(confidential_hart_id, htimedelta, shared_memory), }) .collect(); diff --git a/tools/cove_tap_tool/Cargo.toml b/tools/cove_tap_tool/Cargo.toml index 07a76e12..51b54252 100644 --- a/tools/cove_tap_tool/Cargo.toml +++ b/tools/cove_tap_tool/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] clap = { version="4", features = ["derive"] } # for command line argument parsing +clap-num = "1.1.1" byteorder = "1.5" # to serialize numbers using little/big endianness sha2 = "0.10" # to calculate integrity measurements of kernel, initramfs etc. diff --git a/tools/cove_tap_tool/src/main.rs b/tools/cove_tap_tool/src/main.rs index f25b79ee..30a3f4d2 100644 --- a/tools/cove_tap_tool/src/main.rs +++ b/tools/cove_tap_tool/src/main.rs @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::Error; use clap::{Parser, Subcommand}; +use clap_num::maybe_hex; mod attach; mod error; @@ -39,6 +40,10 @@ enum Commands { Measure { #[arg(short, long)] kernel_file: String, + #[arg(long = "embedded-tap")] + embedded_tap: bool, + #[arg(long = "base-address", value_parser=maybe_hex::, default_value_t = 0x80000000)] + base_address: u64, }, } @@ -90,6 +95,10 @@ fn main() -> Result<(), Error> { tee_public_keys_files, output_file, ), - Commands::Measure { kernel_file } => measure::measure(kernel_file), + Commands::Measure { + kernel_file, + embedded_tap, + base_address, + } => measure::measure(kernel_file, embedded_tap, base_address), }?) } diff --git a/tools/cove_tap_tool/src/measure.rs b/tools/cove_tap_tool/src/measure.rs index c3470c26..905b75a2 100644 --- a/tools/cove_tap_tool/src/measure.rs +++ b/tools/cove_tap_tool/src/measure.rs @@ -9,7 +9,7 @@ pub type DigestType = sha2::Sha384; pub type MeasurementDigest = GenericArray::OutputSize>; -pub fn measure(kernel_file: String) -> Result<(), Error> { +pub fn measure(kernel_file: String, embedded_tap: bool, base_address: u64) -> Result<(), Error> { use std::io::BufReader; use std::io::Read; @@ -18,15 +18,18 @@ pub fn measure(kernel_file: String) -> Result<(), Error> { let kernel = OpenOptions::new().read(true).open(kernel_file)?; let mut buf = BufReader::new(kernel); let mut buffer = [0u8; 4096]; // 1 4KiB page - let mut address = 0x80000000 as u64; + let mut address = base_address; while let Ok(bytes_read) = buf.read(&mut buffer) { if bytes_read == 0 { break; } let header = [buffer[0], buffer[1], buffer[2], buffer[3]]; - if u32::from_le_bytes(header) == riscv_cove_tap::ACE_MAGIC_TAP_START { - (0..4096).for_each(|i| buffer[i] = 0); // security monitor will clear it + if embedded_tap { + if u32::from_le_bytes(header) == riscv_cove_tap::ACE_MAGIC_TAP_START { + (0..4096).for_each(|i| buffer[i] = 0); // security monitor will clear it + } } + if buffer.iter().find(|b| **b != 0).is_some() { use sha2::Digest; let mut hasher = DigestType::new_with_prefix(digest.clone());