blob: a105f6d87e31f5a5852fb815e8d4aeef6a1bec47 [file] [log] [blame]
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +01001#include "api.h"
2
3#include "arch_api.h"
4#include "vm.h"
5
6struct vm secondary_vm[MAX_VMS];
7uint32_t secondary_vm_count;
8struct vm primary_vm;
9
10/**
11 * Returns the number of VMs configured to run.
12 */
13int32_t api_vm_get_count(void)
14{
15 return secondary_vm_count;
16}
17
18/**
19 * Returns the number of vcpus configured in the given VM.
20 */
21int32_t api_vcpu_get_count(uint32_t vm_idx)
22{
23 if (vm_idx >= secondary_vm_count)
24 return -1;
25
26 return secondary_vm[vm_idx].vcpu_count;
27}
28
29/**
30 * Runs the given vcpu of the given vm.
31 */
32int32_t api_vcpu_run(uint32_t vm_idx, uint32_t vcpu_idx, struct vcpu **next)
33{
34 struct vm *vm = secondary_vm + vm_idx;
35 struct vcpu *vcpu;
36
37 /* Only the primary VM can switch vcpus. */
38 if (cpu()->current->vm != &primary_vm)
39 return HF_VCPU_WAIT_FOR_INTERRUPT;
40
41 if (vm_idx >= secondary_vm_count)
42 return HF_VCPU_WAIT_FOR_INTERRUPT;
43
44 vcpu = vm->vcpus + vcpu_idx;
45 if (vcpu_idx >= vm->vcpu_count || !vcpu->is_on)
46 return HF_VCPU_WAIT_FOR_INTERRUPT;
47
48 arch_set_vm_mm(&vm->page_table);
49 *next = vcpu;
50
51 return HF_VCPU_YIELD;
52}
53
54/**
55 * Puts current vcpu in wait for interrupt mode, and returns to the primary
56 * vm.
57 */
58struct vcpu *api_wait_for_interrupt(void)
59{
60 struct vcpu *vcpu = &primary_vm.vcpus[cpu_index(cpu())];
61
62 /* Switch back to primary VM. */
63 arch_set_vm_mm(&primary_vm.page_table);
64
65 /*
66 * Inidicate to primary VM that this vcpu blocked waiting for an
67 * interrupt.
68 */
69 arch_regs_set_retval(&vcpu->regs, HF_VCPU_WAIT_FOR_INTERRUPT);
70
71 return vcpu;
72}