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

libsel4vm: guest cpu requests to vcpus from pcpus #85

Open
wants to merge 1 commit into
base: master
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
23 changes: 23 additions & 0 deletions libsel4vm/include/sel4vm/guest_vm_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ static inline vm_vcpu_t *vm_find_free_unassigned_vcpu(vm_t *vm)
return NULL;
}

/***
* @function vm_find_free_unassigned_cpu(vm)
* Find an unallocated physical cpu
* @param {vm_t *} vm A handle to the vm owning the vcpu
* @return -1 if no pcpu can be found, otherwise the available pcpu
*/
static inline int vm_find_free_unassigned_cpu(vm_t *vm)
{
for (int core = 0; core < CONFIG_MAX_NUM_NODES; core++) {
int core_allocated = 0;
for (int i = 0; i < vm->num_vcpus; i++) {
if (vm->vcpus[i]->target_cpu == core) {
core_allocated = 1;
break;
}
}
if (!core_allocated) {
return core;
}
}
return -1;
}

/***
* @function is_vcpu_online(vcpu)
* Find if a given VCPU is online
Expand Down
19 changes: 14 additions & 5 deletions libsel4vmmplatsupport/src/arch/arm/psci.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,24 @@ int handle_psci(vm_vcpu_t *vcpu, seL4_Word fn_number, bool convention)
smc_set_return_value(&regs, 0x00010000); /* version 1 */
break;
case PSCI_CPU_ON: {
uintptr_t target_cpu = smc_get_arg(&regs, 1);
uintptr_t requested_cpu = smc_get_arg(&regs, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so, my question holds - we get a (v)MPIDR here from the guest and not a linear (seL4 affinity) ID?

uintptr_t entry_point_address = smc_get_arg(&regs, 2);
uintptr_t context_id = smc_get_arg(&regs, 3);
vm_vcpu_t *target_vcpu = vm_vcpu_for_target_cpu(vcpu->vm, target_cpu);
if (target_vcpu == NULL) {
target_vcpu = vm_find_free_unassigned_vcpu(vcpu->vm);
if (target_vcpu && start_new_vcpu(target_vcpu, entry_point_address, context_id, target_cpu) == 0) {
vm_vcpu_t *target_vcpu = NULL;
if ((requested_cpu >= 0) && (requested_cpu < vcpu->vm->num_vcpus)) {
target_vcpu = vcpu->vm->vcpus[requested_cpu];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not work, because requested_cpu is a MPID value now - because that is what a caller passed into the SMC according to the spec. So we need to do a lookup over all our vCPUs.

} else {
smc_set_return_value(&regs, PSCI_INTERNAL_FAILURE);
break;
}

/* Automatically assign vcpu to an unassigned physical cpu */
if (target_vcpu->target_cpu == -1) {
int selected_cpu = vm_find_free_unassigned_cpu(vcpu->vm);
if ((selected_cpu >= 0) && start_new_vcpu(target_vcpu, entry_point_address, context_id, selected_cpu) == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we have to set the MPIDR of the vCPU here also now, so this is in sync with what the caller requested? Can the caller actually starts arbitrary cored here - shouldn't we have prepared the vCPU list in advance, about what cores the caller can start, ie. what cores the VM has.

smc_set_return_value(&regs, PSCI_SUCCESS);
} else {
ZF_LOGE("[vCPU %u] no unused physical core left", vcpu->vcpu_id);
smc_set_return_value(&regs, PSCI_INTERNAL_FAILURE);
}
} else {
Expand Down