Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for CoVE's Deployment Model 3 #4

Open
wants to merge 14 commits into
base: cove-integration
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions arch/riscv/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
45 changes: 42 additions & 3 deletions arch/riscv/include/asm/kvm_cove.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
#include <asm/csr.h>
#include <asm/sbi.h>

#define KVM_COVE_TSM_CAP_PROMOTE_TVM 0x0
#define KVM_COVE_TSM_CAP_ATTESTATION_LOCAL 0x1
#define KVM_COVE_TSM_CAP_ATTESTATION_REMOTE 0x2
#define KVM_COVE_TSM_CAP_AIA 0x3
#define KVM_COVE_TSM_CAP_MRIF 0x4
#define KVM_COVE_TSM_CAP_MEMORY_ALLOCATION 0x5

#define KVM_COVE_PAGE_SIZE_4K (1UL << 12)
#define KVM_COVE_PAGE_SIZE_2MB (1UL << 21)
#define KVM_COVE_PAGE_SIZE_1GB (1UL << 30)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -115,28 +125,54 @@ 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)
{
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 *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);
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);

Expand All @@ -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; };
static inline bool kvm_riscv_cove_capability(unsigned long cap) { return false; };
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 *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)
{
Expand Down
2 changes: 2 additions & 0 deletions arch/riscv/include/asm/kvm_cove_sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

/* 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);
Expand Down
1 change: 1 addition & 0 deletions arch/riscv/include/asm/kvm_vcpu_sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental;
extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor;
#ifdef CONFIG_RISCV_COVE_HOST
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__ */
7 changes: 7 additions & 0 deletions arch/riscv/include/asm/sbi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
SBI_EXT_COVH_DESTROY_TVM,
SBI_EXT_COVH_TVM_ADD_MEMORY_REGION,
SBI_EXT_COVH_TVM_ADD_PGT_PAGES,
Expand Down Expand Up @@ -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;

Expand Down
12 changes: 12 additions & 0 deletions arch/riscv/include/uapi/asm/kvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
};

/*
Expand Down Expand Up @@ -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,
};

Expand Down
18 changes: 18 additions & 0 deletions arch/riscv/kernel/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,24 @@ ENTRY(_start_kernel)
csrw CSR_IE, zero
csrw CSR_IP, zero

#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
/* 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
Expand Down
12 changes: 12 additions & 0 deletions arch/riscv/kernel/vmlinux.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ SECTIONS
}
__init_end = .;

#ifdef CONFIG_RISCV_COVE_GUEST_EMBEDDED_TAP
. = ALIGN(4096);
.cove_tvm_attestation_payload : {
__cove_tap_start = .;
LONG(0xace0ace0)
SHORT(0x0FFA)
FILL(0x00)
. += 4090;
__cove_tap_end = .;
}
#endif

/* Start of data section */
_sdata = .;
RO_DATA(SECTION_ALIGN)
Expand Down
2 changes: 1 addition & 1 deletion arch/riscv/kvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@ kvm-y += aia.o
kvm-y += aia_device.o
kvm-y += aia_aplic.o
kvm-y += aia_imsic.o
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
Loading