1*bb4ee6a4SAndroid Build Coastguard Worker /*
2*bb4ee6a4SAndroid Build Coastguard Worker * Copyright 2020 The ChromiumOS Authors
3*bb4ee6a4SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
4*bb4ee6a4SAndroid Build Coastguard Worker * found in the LICENSE file.
5*bb4ee6a4SAndroid Build Coastguard Worker */
6*bb4ee6a4SAndroid Build Coastguard Worker
7*bb4ee6a4SAndroid Build Coastguard Worker #include <errno.h>
8*bb4ee6a4SAndroid Build Coastguard Worker #include <fcntl.h>
9*bb4ee6a4SAndroid Build Coastguard Worker #include <linux/kvm.h>
10*bb4ee6a4SAndroid Build Coastguard Worker #include <linux/memfd.h>
11*bb4ee6a4SAndroid Build Coastguard Worker #include <stdint.h>
12*bb4ee6a4SAndroid Build Coastguard Worker #include <stdio.h>
13*bb4ee6a4SAndroid Build Coastguard Worker #include <stdlib.h>
14*bb4ee6a4SAndroid Build Coastguard Worker #include <string.h>
15*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/mman.h>
16*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/syscall.h>
17*bb4ee6a4SAndroid Build Coastguard Worker #include <unistd.h>
18*bb4ee6a4SAndroid Build Coastguard Worker
19*bb4ee6a4SAndroid Build Coastguard Worker #include "crosvm.h"
20*bb4ee6a4SAndroid Build Coastguard Worker
21*bb4ee6a4SAndroid Build Coastguard Worker #define KILL_ADDRESS 0x3f9
22*bb4ee6a4SAndroid Build Coastguard Worker
23*bb4ee6a4SAndroid Build Coastguard Worker #ifndef F_LINUX_SPECIFIC_BASE
24*bb4ee6a4SAndroid Build Coastguard Worker #define F_LINUX_SPECIFIC_BASE 1024
25*bb4ee6a4SAndroid Build Coastguard Worker #endif
26*bb4ee6a4SAndroid Build Coastguard Worker
27*bb4ee6a4SAndroid Build Coastguard Worker #ifndef F_ADD_SEALS
28*bb4ee6a4SAndroid Build Coastguard Worker #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
29*bb4ee6a4SAndroid Build Coastguard Worker #endif
30*bb4ee6a4SAndroid Build Coastguard Worker
31*bb4ee6a4SAndroid Build Coastguard Worker #ifndef F_SEAL_SHRINK
32*bb4ee6a4SAndroid Build Coastguard Worker #define F_SEAL_SHRINK 0x0002
33*bb4ee6a4SAndroid Build Coastguard Worker #endif
34*bb4ee6a4SAndroid Build Coastguard Worker
35*bb4ee6a4SAndroid Build Coastguard Worker const uint8_t code[] = {
36*bb4ee6a4SAndroid Build Coastguard Worker // Set a non-zero value for HV_X64_MSR_GUEST_OS_ID
37*bb4ee6a4SAndroid Build Coastguard Worker // to enable hypercalls.
38*bb4ee6a4SAndroid Build Coastguard Worker
39*bb4ee6a4SAndroid Build Coastguard Worker // mov edx, 0xffffffff
40*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xba, 0xff, 0xff, 0xff, 0xff,
41*bb4ee6a4SAndroid Build Coastguard Worker
42*bb4ee6a4SAndroid Build Coastguard Worker // mov eax, 0xffffffff
43*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb8, 0xff, 0xff, 0xff, 0xff,
44*bb4ee6a4SAndroid Build Coastguard Worker
45*bb4ee6a4SAndroid Build Coastguard Worker // mov ecx, 0x40000000 # HV_X64_MSR_GUEST_OS_ID
46*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb9, 0x00, 0x00, 0x00, 0x40,
47*bb4ee6a4SAndroid Build Coastguard Worker
48*bb4ee6a4SAndroid Build Coastguard Worker // wrmsr
49*bb4ee6a4SAndroid Build Coastguard Worker 0x0f, 0x30,
50*bb4ee6a4SAndroid Build Coastguard Worker
51*bb4ee6a4SAndroid Build Coastguard Worker // Establish page at 0x2000 as the hypercall page.
52*bb4ee6a4SAndroid Build Coastguard Worker
53*bb4ee6a4SAndroid Build Coastguard Worker // mov edx, 0x00000000
54*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xba, 0x00, 0x00, 0x00, 0x00,
55*bb4ee6a4SAndroid Build Coastguard Worker
56*bb4ee6a4SAndroid Build Coastguard Worker // mov eax, 0x00002001 # lowest bit is enable bit
57*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb8, 0x01, 0x20, 0x00, 0x00,
58*bb4ee6a4SAndroid Build Coastguard Worker
59*bb4ee6a4SAndroid Build Coastguard Worker // mov ecx, 0x40000001 # HV_X64_MSR_HYPERCALL
60*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb9, 0x01, 0x00, 0x00, 0x40,
61*bb4ee6a4SAndroid Build Coastguard Worker
62*bb4ee6a4SAndroid Build Coastguard Worker // wrmsr
63*bb4ee6a4SAndroid Build Coastguard Worker 0x0f, 0x30,
64*bb4ee6a4SAndroid Build Coastguard Worker
65*bb4ee6a4SAndroid Build Coastguard Worker // We can't test generic hypercalls since they're
66*bb4ee6a4SAndroid Build Coastguard Worker // defined to UD for processors running in real mode.
67*bb4ee6a4SAndroid Build Coastguard Worker
68*bb4ee6a4SAndroid Build Coastguard Worker // for HV_X64_MSR_CONTROL:
69*bb4ee6a4SAndroid Build Coastguard Worker // edx:eax gets transferred as 'control'
70*bb4ee6a4SAndroid Build Coastguard Worker
71*bb4ee6a4SAndroid Build Coastguard Worker // mov edx, 0x05060708
72*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xba, 0x08, 0x07, 0x06, 0x05,
73*bb4ee6a4SAndroid Build Coastguard Worker
74*bb4ee6a4SAndroid Build Coastguard Worker // mov eax, 0x01020304
75*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb8, 0x04, 0x03, 0x02, 0x01,
76*bb4ee6a4SAndroid Build Coastguard Worker
77*bb4ee6a4SAndroid Build Coastguard Worker // mov ecx, 0x40000080 # HV_X64_MSR_SCONTROL
78*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb9, 0x80, 0x00, 0x00, 0x40,
79*bb4ee6a4SAndroid Build Coastguard Worker
80*bb4ee6a4SAndroid Build Coastguard Worker // wrmsr
81*bb4ee6a4SAndroid Build Coastguard Worker 0x0f, 0x30,
82*bb4ee6a4SAndroid Build Coastguard Worker
83*bb4ee6a4SAndroid Build Coastguard Worker // Establish page at 0x3000 as the evt_page.
84*bb4ee6a4SAndroid Build Coastguard Worker
85*bb4ee6a4SAndroid Build Coastguard Worker // mov edx, 0x00000000
86*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xba, 0x00, 0x00, 0x00, 0x00,
87*bb4ee6a4SAndroid Build Coastguard Worker
88*bb4ee6a4SAndroid Build Coastguard Worker // mov eax, 0x00003000
89*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb8, 0x00, 0x30, 0x00, 0x00,
90*bb4ee6a4SAndroid Build Coastguard Worker
91*bb4ee6a4SAndroid Build Coastguard Worker // mov ecx, 0x40000082 # HV_X64_MSR_SIEFP
92*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb9, 0x82, 0x00, 0x00, 0x40,
93*bb4ee6a4SAndroid Build Coastguard Worker
94*bb4ee6a4SAndroid Build Coastguard Worker // wrmsr
95*bb4ee6a4SAndroid Build Coastguard Worker 0x0f, 0x30,
96*bb4ee6a4SAndroid Build Coastguard Worker
97*bb4ee6a4SAndroid Build Coastguard Worker // Establish page at 0x4000 as the 'msg_page'.
98*bb4ee6a4SAndroid Build Coastguard Worker
99*bb4ee6a4SAndroid Build Coastguard Worker // mov edx, 0x00000000
100*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xba, 0x00, 0x00, 0x00, 0x00,
101*bb4ee6a4SAndroid Build Coastguard Worker
102*bb4ee6a4SAndroid Build Coastguard Worker // mov eax, 0x00004000
103*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb8, 0x00, 0x40, 0x00, 0x00,
104*bb4ee6a4SAndroid Build Coastguard Worker
105*bb4ee6a4SAndroid Build Coastguard Worker // mov ecx, 0x40000083 # HV_X64_MSR_SIMP
106*bb4ee6a4SAndroid Build Coastguard Worker 0x66, 0xb9, 0x83, 0x00, 0x00, 0x40,
107*bb4ee6a4SAndroid Build Coastguard Worker
108*bb4ee6a4SAndroid Build Coastguard Worker // wrmsr
109*bb4ee6a4SAndroid Build Coastguard Worker 0x0f, 0x30,
110*bb4ee6a4SAndroid Build Coastguard Worker
111*bb4ee6a4SAndroid Build Coastguard Worker // Request a kill.
112*bb4ee6a4SAndroid Build Coastguard Worker
113*bb4ee6a4SAndroid Build Coastguard Worker // mov dx, 0x3f9
114*bb4ee6a4SAndroid Build Coastguard Worker 0xba, 0xf9, 0x03,
115*bb4ee6a4SAndroid Build Coastguard Worker
116*bb4ee6a4SAndroid Build Coastguard Worker // mov al, 0x1
117*bb4ee6a4SAndroid Build Coastguard Worker 0xb0, 0x01,
118*bb4ee6a4SAndroid Build Coastguard Worker
119*bb4ee6a4SAndroid Build Coastguard Worker // out dx, al
120*bb4ee6a4SAndroid Build Coastguard Worker 0xee,
121*bb4ee6a4SAndroid Build Coastguard Worker
122*bb4ee6a4SAndroid Build Coastguard Worker // hlt
123*bb4ee6a4SAndroid Build Coastguard Worker 0xf4
124*bb4ee6a4SAndroid Build Coastguard Worker };
125*bb4ee6a4SAndroid Build Coastguard Worker
check_synic_access(struct crosvm_vcpu * vcpu,struct crosvm_vcpu_event * evt,uint32_t msr,uint64_t control,uint64_t evt_page,uint64_t msg_page,const char * phase)126*bb4ee6a4SAndroid Build Coastguard Worker int check_synic_access(struct crosvm_vcpu* vcpu, struct crosvm_vcpu_event *evt,
127*bb4ee6a4SAndroid Build Coastguard Worker uint32_t msr, uint64_t control, uint64_t evt_page,
128*bb4ee6a4SAndroid Build Coastguard Worker uint64_t msg_page, const char *phase) {
129*bb4ee6a4SAndroid Build Coastguard Worker if (evt->kind != CROSVM_VCPU_EVENT_KIND_HYPERV_SYNIC) {
130*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Got incorrect exit type before %s: %d\n", phase,
131*bb4ee6a4SAndroid Build Coastguard Worker evt->kind);
132*bb4ee6a4SAndroid Build Coastguard Worker return 1;
133*bb4ee6a4SAndroid Build Coastguard Worker }
134*bb4ee6a4SAndroid Build Coastguard Worker if (evt->hyperv_synic.msr != msr ||
135*bb4ee6a4SAndroid Build Coastguard Worker evt->hyperv_synic._reserved != 0 ||
136*bb4ee6a4SAndroid Build Coastguard Worker evt->hyperv_synic.control != control ||
137*bb4ee6a4SAndroid Build Coastguard Worker evt->hyperv_synic.evt_page != evt_page ||
138*bb4ee6a4SAndroid Build Coastguard Worker evt->hyperv_synic.msg_page != msg_page) {
139*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Got unexpected synic message after %s: "
140*bb4ee6a4SAndroid Build Coastguard Worker "0x%x vs 0x%x, 0x%lx vs 0x%lx, 0x%lx vs 0x%lx, "
141*bb4ee6a4SAndroid Build Coastguard Worker "0x%lx vs 0x%lx\n",
142*bb4ee6a4SAndroid Build Coastguard Worker phase, msr, evt->hyperv_synic.msr,
143*bb4ee6a4SAndroid Build Coastguard Worker control, evt->hyperv_synic.control,
144*bb4ee6a4SAndroid Build Coastguard Worker evt_page, evt->hyperv_synic.evt_page,
145*bb4ee6a4SAndroid Build Coastguard Worker msg_page, evt->hyperv_synic.msg_page);
146*bb4ee6a4SAndroid Build Coastguard Worker return 1;
147*bb4ee6a4SAndroid Build Coastguard Worker }
148*bb4ee6a4SAndroid Build Coastguard Worker
149*bb4ee6a4SAndroid Build Coastguard Worker if (crosvm_vcpu_resume(vcpu) != 0) {
150*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Failed to resume after %s\n", phase);
151*bb4ee6a4SAndroid Build Coastguard Worker return 1;
152*bb4ee6a4SAndroid Build Coastguard Worker }
153*bb4ee6a4SAndroid Build Coastguard Worker
154*bb4ee6a4SAndroid Build Coastguard Worker if (crosvm_vcpu_wait(vcpu, evt) != 0) {
155*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Failed to wait after %s\n", phase);
156*bb4ee6a4SAndroid Build Coastguard Worker return 1;
157*bb4ee6a4SAndroid Build Coastguard Worker }
158*bb4ee6a4SAndroid Build Coastguard Worker return 0;
159*bb4ee6a4SAndroid Build Coastguard Worker }
160*bb4ee6a4SAndroid Build Coastguard Worker
main(int argc,char ** argv)161*bb4ee6a4SAndroid Build Coastguard Worker int main(int argc, char** argv) {
162*bb4ee6a4SAndroid Build Coastguard Worker struct crosvm* crosvm = NULL;
163*bb4ee6a4SAndroid Build Coastguard Worker uint64_t cap_args[4] = {0};
164*bb4ee6a4SAndroid Build Coastguard Worker
165*bb4ee6a4SAndroid Build Coastguard Worker int ret = crosvm_connect(&crosvm);
166*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
167*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to connect to crosvm: %d\n", ret);
168*bb4ee6a4SAndroid Build Coastguard Worker return 1;
169*bb4ee6a4SAndroid Build Coastguard Worker }
170*bb4ee6a4SAndroid Build Coastguard Worker
171*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_reserve_range(crosvm, CROSVM_ADDRESS_SPACE_IOPORT,
172*bb4ee6a4SAndroid Build Coastguard Worker KILL_ADDRESS, 1);
173*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
174*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to reserve kill port: %d\n", ret);
175*bb4ee6a4SAndroid Build Coastguard Worker return 1;
176*bb4ee6a4SAndroid Build Coastguard Worker }
177*bb4ee6a4SAndroid Build Coastguard Worker
178*bb4ee6a4SAndroid Build Coastguard Worker // VM mem layout:
179*bb4ee6a4SAndroid Build Coastguard Worker // null page, code page, hypercall page, synic evt_page, synic msg_page
180*bb4ee6a4SAndroid Build Coastguard Worker int mem_size = 0x4000;
181*bb4ee6a4SAndroid Build Coastguard Worker int mem_fd = syscall(SYS_memfd_create, "guest_mem",
182*bb4ee6a4SAndroid Build Coastguard Worker MFD_CLOEXEC | MFD_ALLOW_SEALING);
183*bb4ee6a4SAndroid Build Coastguard Worker if (mem_fd < 0) {
184*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to create guest memfd: %d\n", errno);
185*bb4ee6a4SAndroid Build Coastguard Worker return 1;
186*bb4ee6a4SAndroid Build Coastguard Worker }
187*bb4ee6a4SAndroid Build Coastguard Worker ret = ftruncate(mem_fd, mem_size);
188*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
189*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to set size of guest memory: %d\n", errno);
190*bb4ee6a4SAndroid Build Coastguard Worker return 1;
191*bb4ee6a4SAndroid Build Coastguard Worker }
192*bb4ee6a4SAndroid Build Coastguard Worker uint8_t *mem = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED,
193*bb4ee6a4SAndroid Build Coastguard Worker mem_fd, 0x0);
194*bb4ee6a4SAndroid Build Coastguard Worker if (mem == MAP_FAILED) {
195*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to mmap guest memory: %d\n", errno);
196*bb4ee6a4SAndroid Build Coastguard Worker return 1;
197*bb4ee6a4SAndroid Build Coastguard Worker }
198*bb4ee6a4SAndroid Build Coastguard Worker fcntl(mem_fd, F_ADD_SEALS, F_SEAL_SHRINK);
199*bb4ee6a4SAndroid Build Coastguard Worker memcpy(mem, code, sizeof(code));
200*bb4ee6a4SAndroid Build Coastguard Worker
201*bb4ee6a4SAndroid Build Coastguard Worker // Before MSR verify hypercall page is zero
202*bb4ee6a4SAndroid Build Coastguard Worker int i;
203*bb4ee6a4SAndroid Build Coastguard Worker for (i = 0; i < 5; ++i) {
204*bb4ee6a4SAndroid Build Coastguard Worker if (mem[0x1000 + i]) {
205*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Hypercall page isn't zero\n");
206*bb4ee6a4SAndroid Build Coastguard Worker return 1;
207*bb4ee6a4SAndroid Build Coastguard Worker }
208*bb4ee6a4SAndroid Build Coastguard Worker }
209*bb4ee6a4SAndroid Build Coastguard Worker
210*bb4ee6a4SAndroid Build Coastguard Worker struct crosvm_memory *mem_obj;
211*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_create_memory(crosvm, mem_fd, 0x0, mem_size, 0x1000,
212*bb4ee6a4SAndroid Build Coastguard Worker false, false, &mem_obj);
213*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
214*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to create memory in crosvm: %d\n", ret);
215*bb4ee6a4SAndroid Build Coastguard Worker return 1;
216*bb4ee6a4SAndroid Build Coastguard Worker }
217*bb4ee6a4SAndroid Build Coastguard Worker
218*bb4ee6a4SAndroid Build Coastguard Worker struct crosvm_vcpu* vcpu = NULL;
219*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_get_vcpu(crosvm, 0, &vcpu);
220*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
221*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to get vcpu #0: %d\n", ret);
222*bb4ee6a4SAndroid Build Coastguard Worker return 1;
223*bb4ee6a4SAndroid Build Coastguard Worker }
224*bb4ee6a4SAndroid Build Coastguard Worker
225*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_start(crosvm);
226*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
227*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to start vm: %d\n", ret);
228*bb4ee6a4SAndroid Build Coastguard Worker return 1;
229*bb4ee6a4SAndroid Build Coastguard Worker }
230*bb4ee6a4SAndroid Build Coastguard Worker
231*bb4ee6a4SAndroid Build Coastguard Worker struct crosvm_vcpu_event evt = {0};
232*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_vcpu_wait(vcpu, &evt);
233*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
234*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "failed to wait for vm start: %d\n", ret);
235*bb4ee6a4SAndroid Build Coastguard Worker return 1;
236*bb4ee6a4SAndroid Build Coastguard Worker }
237*bb4ee6a4SAndroid Build Coastguard Worker if (evt.kind != CROSVM_VCPU_EVENT_KIND_INIT) {
238*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Got unexpected exit type: %d\n", evt.kind);
239*bb4ee6a4SAndroid Build Coastguard Worker return 1;
240*bb4ee6a4SAndroid Build Coastguard Worker }
241*bb4ee6a4SAndroid Build Coastguard Worker
242*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_enable_capability(crosvm, 0, 0, cap_args);
243*bb4ee6a4SAndroid Build Coastguard Worker if (ret != -EINVAL) {
244*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Unexpected crosvm_enable_capability result: %d\n",
245*bb4ee6a4SAndroid Build Coastguard Worker ret);
246*bb4ee6a4SAndroid Build Coastguard Worker return 1;
247*bb4ee6a4SAndroid Build Coastguard Worker }
248*bb4ee6a4SAndroid Build Coastguard Worker
249*bb4ee6a4SAndroid Build Coastguard Worker ret = crosvm_vcpu_enable_capability(vcpu, KVM_CAP_HYPERV_SYNIC, 0,
250*bb4ee6a4SAndroid Build Coastguard Worker cap_args);
251*bb4ee6a4SAndroid Build Coastguard Worker if (ret) {
252*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "crosvm_vcpu_enable_capability() failed: %d\n", ret);
253*bb4ee6a4SAndroid Build Coastguard Worker return 1;
254*bb4ee6a4SAndroid Build Coastguard Worker }
255*bb4ee6a4SAndroid Build Coastguard Worker
256*bb4ee6a4SAndroid Build Coastguard Worker {
257*bb4ee6a4SAndroid Build Coastguard Worker struct kvm_sregs sregs = {0};
258*bb4ee6a4SAndroid Build Coastguard Worker crosvm_vcpu_get_sregs(vcpu, &sregs);
259*bb4ee6a4SAndroid Build Coastguard Worker sregs.cs.base = 0;
260*bb4ee6a4SAndroid Build Coastguard Worker sregs.cs.selector = 0;
261*bb4ee6a4SAndroid Build Coastguard Worker sregs.es.base = 0;
262*bb4ee6a4SAndroid Build Coastguard Worker sregs.es.selector = 0;
263*bb4ee6a4SAndroid Build Coastguard Worker crosvm_vcpu_set_sregs(vcpu, &sregs);
264*bb4ee6a4SAndroid Build Coastguard Worker
265*bb4ee6a4SAndroid Build Coastguard Worker struct kvm_regs regs = {0};
266*bb4ee6a4SAndroid Build Coastguard Worker crosvm_vcpu_get_regs(vcpu, ®s);
267*bb4ee6a4SAndroid Build Coastguard Worker regs.rip = 0x1000;
268*bb4ee6a4SAndroid Build Coastguard Worker regs.rflags = 2;
269*bb4ee6a4SAndroid Build Coastguard Worker crosvm_vcpu_set_regs(vcpu, ®s);
270*bb4ee6a4SAndroid Build Coastguard Worker }
271*bb4ee6a4SAndroid Build Coastguard Worker
272*bb4ee6a4SAndroid Build Coastguard Worker if (crosvm_vcpu_resume(vcpu) != 0) {
273*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Failed to resume after init\n");
274*bb4ee6a4SAndroid Build Coastguard Worker return 1;
275*bb4ee6a4SAndroid Build Coastguard Worker }
276*bb4ee6a4SAndroid Build Coastguard Worker
277*bb4ee6a4SAndroid Build Coastguard Worker if (crosvm_vcpu_wait(vcpu, &evt) != 0) {
278*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Failed to wait after init\n");
279*bb4ee6a4SAndroid Build Coastguard Worker return 1;
280*bb4ee6a4SAndroid Build Coastguard Worker }
281*bb4ee6a4SAndroid Build Coastguard Worker if (check_synic_access(vcpu, &evt, 0x40000080, 0x506070801020304, 0, 0,
282*bb4ee6a4SAndroid Build Coastguard Worker "synic msg #1")) {
283*bb4ee6a4SAndroid Build Coastguard Worker return 1;
284*bb4ee6a4SAndroid Build Coastguard Worker }
285*bb4ee6a4SAndroid Build Coastguard Worker
286*bb4ee6a4SAndroid Build Coastguard Worker // After first MSR verify hypercall page is non-zero
287*bb4ee6a4SAndroid Build Coastguard Worker uint8_t value = 0;
288*bb4ee6a4SAndroid Build Coastguard Worker for (i = 0; i < 5; ++i) {
289*bb4ee6a4SAndroid Build Coastguard Worker value |= mem[0x1000+i];
290*bb4ee6a4SAndroid Build Coastguard Worker }
291*bb4ee6a4SAndroid Build Coastguard Worker if (value == 0) {
292*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Hypercall page is still zero\n");
293*bb4ee6a4SAndroid Build Coastguard Worker return 1;
294*bb4ee6a4SAndroid Build Coastguard Worker }
295*bb4ee6a4SAndroid Build Coastguard Worker
296*bb4ee6a4SAndroid Build Coastguard Worker if (check_synic_access(vcpu, &evt, 0x40000082, 0x506070801020304, 0x3000,
297*bb4ee6a4SAndroid Build Coastguard Worker 0, "synic msg #2")) {
298*bb4ee6a4SAndroid Build Coastguard Worker return 1;
299*bb4ee6a4SAndroid Build Coastguard Worker }
300*bb4ee6a4SAndroid Build Coastguard Worker
301*bb4ee6a4SAndroid Build Coastguard Worker if (check_synic_access(vcpu, &evt, 0x40000083, 0x506070801020304, 0x3000,
302*bb4ee6a4SAndroid Build Coastguard Worker 0x4000, "synic msg #3")) {
303*bb4ee6a4SAndroid Build Coastguard Worker return 1;
304*bb4ee6a4SAndroid Build Coastguard Worker }
305*bb4ee6a4SAndroid Build Coastguard Worker
306*bb4ee6a4SAndroid Build Coastguard Worker if (evt.kind != CROSVM_VCPU_EVENT_KIND_IO_ACCESS) {
307*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Got incorrect exit type after synic #3: %d\n",
308*bb4ee6a4SAndroid Build Coastguard Worker evt.kind);
309*bb4ee6a4SAndroid Build Coastguard Worker return 1;
310*bb4ee6a4SAndroid Build Coastguard Worker }
311*bb4ee6a4SAndroid Build Coastguard Worker if (evt.io_access.address_space != CROSVM_ADDRESS_SPACE_IOPORT ||
312*bb4ee6a4SAndroid Build Coastguard Worker evt.io_access.address != KILL_ADDRESS ||
313*bb4ee6a4SAndroid Build Coastguard Worker !evt.io_access.is_write ||
314*bb4ee6a4SAndroid Build Coastguard Worker evt.io_access.length != 1 ||
315*bb4ee6a4SAndroid Build Coastguard Worker evt.io_access.data[0] != 1) {
316*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Didn't see kill request from VM\n");
317*bb4ee6a4SAndroid Build Coastguard Worker return 1;
318*bb4ee6a4SAndroid Build Coastguard Worker }
319*bb4ee6a4SAndroid Build Coastguard Worker
320*bb4ee6a4SAndroid Build Coastguard Worker fprintf(stderr, "Saw kill request from VM, exiting\n");
321*bb4ee6a4SAndroid Build Coastguard Worker
322*bb4ee6a4SAndroid Build Coastguard Worker return 0;
323*bb4ee6a4SAndroid Build Coastguard Worker }
324