-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvcpu.c
More file actions
96 lines (76 loc) · 1.94 KB
/
vcpu.c
File metadata and controls
96 lines (76 loc) · 1.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
* SPDX-License-Identifier: GPL-2.0
* Copyright (c) 2026 Ant Group Corporation.
*
* vcpu.c - vcpu interface
*/
#include <linux/sched.h>
#include "instance.h"
#include "vmx.h"
static inline int vcpu_allocate_vcpu_no(struct instance *instp)
{
int vcpu_no = -1;
spin_lock(&instp->vcpu_lock);
vcpu_no = find_first_zero_bit(instp->vcpu_bitmap, VM_MAX_VCPUS);
if (vcpu_no < VM_MAX_VCPUS)
__set_bit(vcpu_no, instp->vcpu_bitmap);
spin_unlock(&instp->vcpu_lock);
if (vcpu_no >= VM_MAX_VCPUS)
vcpu_no = -1;
return vcpu_no;
}
static inline void vcpu_free_vcpu_no(struct instance *instp, int vcpu_no)
{
spin_lock(&instp->vcpu_lock);
if (vcpu_no >= 0)
__clear_bit(vcpu_no, instp->vcpu_bitmap);
spin_unlock(&instp->vcpu_lock);
}
int vcpu_alloc(struct instance *instp, struct slimvm_config *conf)
{
struct vmx_vcpu *vcpu;
int vcpu_no;
vcpu_no = vcpu_allocate_vcpu_no(instp);
if (vcpu_no == -1) {
slimvm_error("Allocate vcpu_no failed!");
return -ENOMEM;
}
vcpu = vmx_create_vcpu(conf, instp);
if (!vcpu) {
vcpu_free_vcpu_no(instp, vcpu_no);
return -ENOMEM;
}
vcpu->vcpu_no = vcpu_no;
if (!cmpxchg(&instp->mm, NULL, current->mm))
atomic_inc(¤t->mm->mm_count);
spin_lock(&instp->vcpu_lock);
instp->vcpus[vcpu_no] = vcpu;
spin_unlock(&instp->vcpu_lock);
return vcpu_no;
}
void vcpu_release(struct instance *instp, int vcpu_no)
{
struct vmx_vcpu *vcpu;
spin_lock(&instp->vcpu_lock);
if (!instp->vcpus[vcpu_no]) {
spin_unlock(&instp->vcpu_lock);
return;
}
vcpu = instp->vcpus[vcpu_no];
__clear_bit(vcpu_no, instp->vcpu_bitmap);
instp->vcpus[vcpu_no] = NULL;
spin_unlock(&instp->vcpu_lock);
vmx_destroy_vcpu(vcpu);
}
void vcpu_inject_nmi(struct instance *instp, int vcpu_no)
{
struct vmx_vcpu *vcpu;
spin_lock(&instp->vcpu_lock);
if (!instp->vcpus[vcpu_no]) {
spin_unlock(&instp->vcpu_lock);
return;
}
vcpu = instp->vcpus[vcpu_no];
vmx_make_request(VMX_REQ_NMI, vcpu);
spin_unlock(&instp->vcpu_lock);
}