Skip to content

Commit

Permalink
smc_cap: Allow SMC forwarding, if configured
Browse files Browse the repository at this point in the history
Implemented a custom SMC call handler. It will check for a capability
associated with the SMC function ID called from the VM. If it exists,
then the SMC is forwarded to the microkernel so it can make the actual
SMC call. If it does not exist then the default SMC handler is called.
This allows PSCI emulation to continue working.

Register this new function as the VM's smc_handler_callback.

Signed-off-by: Robbie VanVossen <[email protected]>
  • Loading branch information
Alex Pavey authored and kent-mcleod committed Sep 14, 2023
1 parent 280208d commit 2941a4b
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions components/VM_Arm/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include <sel4vmmplatsupport/arch/guest_reboot.h>
#include <sel4vmmplatsupport/arch/guest_vcpu_fault.h>
#include <sel4vmmplatsupport/guest_vcpu_util.h>
#include <sel4vmmplatsupport/arch/smc.h>

#include <sel4utils/process.h>
#include <sel4utils/irq_server.h>
Expand Down Expand Up @@ -127,6 +128,10 @@ seL4_CPtr camkes_get_smmu_cb_cap();
seL4_CPtr camkes_get_smmu_sid_cap();
#endif

#ifdef CONFIG_ALLOW_SMC_CALLS
seL4_CPtr camkes_get_smc_cap(seL4_Word smc_call);
#endif

int get_crossvm_irq_num(void)
{
return free_plat_interrupts[0];
Expand Down Expand Up @@ -1141,6 +1146,20 @@ memory_fault_result_t unhandled_mem_fault_callback(vm_t *vm, vm_vcpu_t *vcpu,
return FAULT_ERROR;
}

#ifdef CONFIG_ALLOW_SMC_CALLS
int vm_smc_handler(vm_vcpu_t *vcpu, seL4_UserContext *regs)
{
int err;
seL4_Word id = smc_get_function_id(regs);
seL4_ARM_SMC smc_cap = camkes_get_smc_cap(id);
if (smc_cap) {
return smc_forward(vcpu, regs, smc_cap);
} else {
return vm_smc_handle_default(vcpu, regs);
}
}
#endif

static int main_continued(void)
{
vm_t vm;
Expand Down Expand Up @@ -1233,6 +1252,11 @@ static int main_continued(void)
err = vm_create_default_irq_controller(&vm);
assert(!err);

#ifdef CONFIG_ALLOW_SMC_CALLS
err = vm_register_smc_handler_callback(&vm, vm_smc_handler);
assert(!err);
#endif

/* Create CPUs and DTB node */
for (int i = 0; i < NUM_VCPUS; i++) {
vm_vcpu_t *new_vcpu = create_vmm_plat_vcpu(&vm, VM_PRIO - 1);
Expand Down

0 comments on commit 2941a4b

Please sign in to comment.