Skip to content

Commit

Permalink
Enable CoVE guests to run in an environment that does not have AIA. D…
Browse files Browse the repository at this point in the history
…etect AIA

presence by discovering that the TEE security monitor (TSM) implements the SBI
COVI extension. If AIA is not present, inject external interrupts using the
HVIP register when resuming execution of a virtual processor via the COVH
tvm_vcpu_run() call.

Signed-off-by: Wojciech Ozga <woz@zurich.ibm.com>
  • Loading branch information
wojciechozga committed Jun 19, 2024
1 parent e46b07b commit 1910bf1
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 11 deletions.
4 changes: 4 additions & 0 deletions arch/riscv/include/asm/kvm_cove.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include <asm/csr.h>
#include <asm/sbi.h>

DECLARE_STATIC_KEY_FALSE(kvm_riscv_covi_available);
#define kvm_riscv_covi_available() \
static_branch_unlikely(&kvm_riscv_covi_available)

#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
1 change: 1 addition & 0 deletions arch/riscv/kvm/aia.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ static int hgei_parent_irq;
unsigned int kvm_riscv_aia_nr_hgei;
unsigned int kvm_riscv_aia_max_ids;
DEFINE_STATIC_KEY_FALSE(kvm_riscv_aia_available);
DEFINE_STATIC_KEY_FALSE(kvm_riscv_covi_available);

static int aia_find_hgei(struct kvm_vcpu *owner)
{
Expand Down
8 changes: 6 additions & 2 deletions arch/riscv/kvm/cove.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,9 +589,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.
* COVI bind call requires the TVM to be in finalized state.
*/
if (tvcpuc->imsic.bind_required) {
if (likely(kvm_riscv_covi_available()) && tvcpuc->imsic.bind_required) {
tvcpuc->imsic.bind_required = false;
rc = kvm_riscv_cove_vcpu_imsic_bind(vcpu, BIT(tvcpuc->imsic.vsfile_hgei));
if (rc) {
Expand Down Expand Up @@ -988,6 +988,10 @@ int kvm_riscv_cove_init(void)
if (sbi_probe_extension(SBI_EXT_COVH) <= 0 || !kvm_riscv_nacl_available())
return -EOPNOTSUPP;

if (sbi_probe_extension(SBI_EXT_COVI) > 0) {
static_branch_enable(&kvm_riscv_covi_available);
}

rc = sbi_covh_tsm_get_info(&tinfo);
if (rc < 0)
return -EINVAL;
Expand Down
9 changes: 4 additions & 5 deletions arch/riscv/kvm/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
if (unlikely(kvm_riscv_cove_enabled()))
if (unlikely(kvm_riscv_cove_enabled()) && likely(kvm_riscv_covi_available()))
goto enable_aia;

hedeleg = 0;
Expand Down
11 changes: 7 additions & 4 deletions arch/riscv/kvm/vcpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,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_aia_initialized(vcpu->kvm))
return -ENXIO;

if (copy_from_user(&irq, argp, sizeof(irq)))
Expand Down Expand Up @@ -1325,8 +1325,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))
/*
* Do not update HVIP CSR for TVMs with AIA because AIA
* provides alternative method to inject interrupts.
*/
if (!is_cove_vcpu(vcpu) || !kvm_riscv_covi_available())
kvm_riscv_update_hvip(vcpu);

if (ret <= 0 ||
Expand Down

0 comments on commit 1910bf1

Please sign in to comment.