@@ -9,14 +9,18 @@ CPU Virtualization
9
9
10
10
ACRN Hypervisor CPU Virtualization Components
11
11
12
+ The following sections discuss the major modules (shown in blue) in the
13
+ CPU virtualization overview shown in :numref: `hv-cpu-virt-components `.
14
+
12
15
Based on Intel VT-x virtualization technology, ACRN emulates a virtual CPU
13
16
(vCPU) with the following methods:
14
17
15
18
- **core partition **: one vCPU is dedicated and associated with one
16
19
physical CPU (pCPU),
17
20
making much of hardware register emulation simply
18
21
pass-through and provides good isolation for physical interrupt
19
- and guest execution.
22
+ and guest execution. (See `Static CPU Partitioning `_ for more
23
+ information.)
20
24
21
25
- **simple schedule **: only two thread loops are maintained for a CPU -
22
26
vCPU thread and default idle thread. A CPU runs most of the time in
@@ -25,8 +29,137 @@ Based on Intel VT-x virtualization technology, ACRN emulates a virtual CPU
25
29
operation needs it to stay in VMX root mode, such as when waiting for
26
30
an I/O request from DM or ready to destroy.
27
31
28
- The following sections discuss the major modules (shown in blue) in the
29
- CPU virtualization overview shown in :numref: `hv-cpu-virt-components `.
32
+ Static CPU Partitioning
33
+ ***********************
34
+
35
+ CPU partitioning is a policy for mapping a virtual
36
+ CPU (VCPU) to a physical CPU. The current ACRN implementation forces a
37
+ static 1:1 mapping between VCPUs and physical CPUs and does
38
+ not support multiple VCPUs running on a physical CPU and does not
39
+ support VCPU migration from one physical CPU to another.
40
+
41
+ ACRN forces a fixed 1:1 mapping between a VCPU and a physical CPU when
42
+ creating a VCPU for the guest Operating System. This makes the VCPU
43
+ management code much simpler.
44
+
45
+ An array is used to track the physical CPU allocation information. When
46
+ a VCPU is created, we query, allocate, and update the array to map the
47
+ VCPU to an available physical CPU.
48
+
49
+ The physical CPU number assignment for each guest is pre-defined. For
50
+ example, on a platform with four CPU cores, one physical CPU is assigned
51
+ to run the Service Operating System (SOS) and other three physical CPUs
52
+ are assigned to run the User Operating System (UOS) instances.
53
+
54
+ .. note ::
55
+
56
+ To improvement SOS boot time, all physical CPUs are assigned to the SOS
57
+ during the SOS boot. Afterward, the physical CPUs defined for the UOS
58
+ are allocated by the Device Model (DM) by running the launch_uos.sh
59
+ script.
60
+
61
+ CPU management in SOS
62
+ =====================
63
+
64
+ With ACRN, all ACPI table entries are pass-thru to the SOS, including
65
+ the Multiple Interrupt Controller Table (MADT). The SOS sees all
66
+ physical CPUs by parsing the MADT when the SOS kernel boots. All
67
+ physical CPUs are initially assigned to the SOS by creating the same
68
+ number of virtual CPUs.
69
+
70
+ When the SOS boot is finished, it releases the physical CPUs intended
71
+ for UOS use.
72
+
73
+ Here is an example flow of CPU allocation on a multi-core platform.
74
+
75
+ .. figure :: images/static-core-image2.png
76
+ :width: 600px
77
+ :align: center
78
+ :name: static-core-cpu-allocation
79
+
80
+ CPU allocation on a multi-core platform
81
+
82
+ CPU management in UOS
83
+ =====================
84
+
85
+ From the UOS point of view, CPU management is very simple, using a
86
+ hypercall to create the virtual CPUs. Here's an example from from the DM
87
+ code:
88
+
89
+ .. code-block :: c
90
+
91
+ int vm_create_vcpu(struct vmctx *ctx, uint16_t vcpu_id)
92
+ {
93
+ struct acrn_create_vcpu cv;
94
+ int error;
95
+
96
+ bzero(&cv, sizeof(struct acrn_create_vcpu));
97
+ cv.vcpu_id = vcpu_id;
98
+ error = ioctl(ctx->fd, IC_CREATE_VCPU, &cv);
99
+ return error;
100
+ }
101
+
102
+ The VHM will respond to the ioctl:
103
+
104
+ .. code-block :: c
105
+
106
+ case IC_CREATE_VCPU: {
107
+ struct acrn_create_vcpu cv;
108
+
109
+ if (copy_from_user(&cv, (void *)ioctl_param,
110
+ sizeof(struct acrn_create_vcpu)))
111
+ return -EFAULT;
112
+
113
+ ret = acrn_hypercall2(HC_CREATE_VCPU, vm->vmid,
114
+ virt_to_phys(&cv));
115
+ if (ret < 0) {
116
+ pr_err("vhm: failed to create vcpu %d!\\n",
117
+ cv.vcpu_id);
118
+ return -EFAULT;
119
+ }
120
+
121
+ atomic_inc(&vm->vcpu_num);
122
+ return ret;
123
+ }
124
+
125
+ The hypercall ``HC_CREATE_VCPU `` is handled in the hypervisor with
126
+ the parameter:
127
+
128
+ .. code-block :: c
129
+
130
+ struct acrn_create_vcpu {
131
+ /** the virtual CPU ID for the VCPU created */
132
+ uint16_t vcpu_id;
133
+ /** the physical CPU ID for the VCPU created */
134
+ uint16_t pcpu_id;
135
+ } __attribute__((aligned(8)));
136
+
137
+ CPU assignment management in HV
138
+ ===============================
139
+
140
+ When we create a VCPU in the hypervisor, an available physical CPU is
141
+ picked and marked as used. When we destroy the VCPU, we mark the
142
+ physical CPU as available again.
143
+
144
+ .. figure :: images/static-core-image1.png
145
+ :width: 600px
146
+ :align: center
147
+ :name: static-core-cpu-assign
148
+
149
+ HV CPU Assignment Management
150
+
151
+ #. ``allocate_pcpu() `` queries the physical CPU allocation info to get an
152
+ available physical CPU and marks physical CPU as not available
153
+ #. Physical CPU info is passed to ``create_vcpu() `` and a mapping is built
154
+ between the physical CPU and virtual CPU
155
+ #. When the VCPU is destroyed VCPU, the physical CPU is passed to the
156
+ ``free_pcpu() `` function
157
+ #. ``free_pcpu() `` marks the physical CPU available again.
158
+
159
+ Currently, the ACRN hypervisor does not support virtual CPU migration to
160
+ different physical CPUs. This means no changes to the virtual CPU to
161
+ physical CPU can happen without first calling destroy_vcpu.
162
+
30
163
31
164
.. _vCPU_lifecycle :
32
165
0 commit comments