blob: 00304739bf3328813b7e9ef783ef5d2fe69692d1 [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{
Andrew Scull7364a8e2018-07-19 15:39:29 +010023 if (vm_idx >= secondary_vm_count) {
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010024 return -1;
Andrew Scull7364a8e2018-07-19 15:39:29 +010025 }
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010026
27 return secondary_vm[vm_idx].vcpu_count;
28}
29
30/**
31 * Runs the given vcpu of the given vm.
32 */
33int32_t api_vcpu_run(uint32_t vm_idx, uint32_t vcpu_idx, struct vcpu **next)
34{
35 struct vm *vm = secondary_vm + vm_idx;
36 struct vcpu *vcpu;
37
38 /* Only the primary VM can switch vcpus. */
Andrew Scull7364a8e2018-07-19 15:39:29 +010039 if (cpu()->current->vm != &primary_vm) {
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010040 return HF_VCPU_WAIT_FOR_INTERRUPT;
Andrew Scull7364a8e2018-07-19 15:39:29 +010041 }
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010042
Andrew Scull7364a8e2018-07-19 15:39:29 +010043 if (vm_idx >= secondary_vm_count) {
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010044 return HF_VCPU_WAIT_FOR_INTERRUPT;
Andrew Scull7364a8e2018-07-19 15:39:29 +010045 }
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010046
47 vcpu = vm->vcpus + vcpu_idx;
Andrew Scull7364a8e2018-07-19 15:39:29 +010048 if (vcpu_idx >= vm->vcpu_count || !vcpu->is_on) {
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010049 return HF_VCPU_WAIT_FOR_INTERRUPT;
Andrew Scull7364a8e2018-07-19 15:39:29 +010050 }
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010051
Wedson Almeida Filho84a30a02018-07-23 20:05:05 +010052 vm_set_current(vm);
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010053 *next = vcpu;
54
55 return HF_VCPU_YIELD;
56}
57
58/**
59 * Puts current vcpu in wait for interrupt mode, and returns to the primary
60 * vm.
61 */
62struct vcpu *api_wait_for_interrupt(void)
63{
64 struct vcpu *vcpu = &primary_vm.vcpus[cpu_index(cpu())];
65
66 /* Switch back to primary VM. */
Wedson Almeida Filho84a30a02018-07-23 20:05:05 +010067 vm_set_current(&primary_vm);
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010068
69 /*
70 * Inidicate to primary VM that this vcpu blocked waiting for an
71 * interrupt.
72 */
73 arch_regs_set_retval(&vcpu->regs, HF_VCPU_WAIT_FOR_INTERRUPT);
74
75 return vcpu;
76}