1 /*
2  * Copyright 2018 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #include <stdint.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #include "crosvm.h"
13 
main(int argc,char ** argv)14 int main(int argc, char** argv) {
15     struct crosvm *crosvm;
16     int ret = crosvm_connect(&crosvm);
17     if (ret) {
18         fprintf(stderr, "failed to connect to crosvm: %d\n", ret);
19         return 1;
20     }
21 
22     struct kvm_pic_state pic_state;
23     ret = crosvm_get_pic_state(crosvm, false, &pic_state);
24     if (ret < 0) {
25         fprintf(stderr, "failed to get initial PIC1 state: %d\n", ret);
26         return 1;
27     }
28 
29     if (pic_state.auto_eoi) {
30         fprintf(stderr, "unexpected value of auto_eoi flag\n");
31         return 1;
32     }
33 
34     pic_state.auto_eoi = true;
35     ret = crosvm_set_pic_state(crosvm, false, &pic_state);
36     if (ret < 0) {
37         fprintf(stderr, "failed to update PIC1 state: %d\n", ret);
38         return 1;
39     }
40 
41     ret = crosvm_get_pic_state(crosvm, false, &pic_state);
42     if (ret < 0) {
43         fprintf(stderr, "failed to get updated PIC1 state: %d\n", ret);
44         return 1;
45     }
46 
47     if (!pic_state.auto_eoi) {
48         fprintf(stderr, "unexpected value of auto_eoi flag after update\n");
49         return 1;
50     }
51 
52     // Test retrieving and setting IOAPIC state.
53     struct kvm_ioapic_state ioapic_state;
54     ret = crosvm_get_ioapic_state(crosvm, &ioapic_state);
55     if (ret < 0) {
56         fprintf(stderr, "failed to get initial PIC1 state: %d\n", ret);
57         return 1;
58     }
59 
60     fprintf(stderr, "IOAPIC ID: %d\n", ioapic_state.id);
61 
62     if (ioapic_state.id != 0) {
63         fprintf(stderr, "unexpected value of IOAPIC ID: %d\n", ioapic_state.id);
64         return 1;
65     }
66 
67     ioapic_state.id = 1;
68     ret = crosvm_set_ioapic_state(crosvm, &ioapic_state);
69     if (ret < 0) {
70         fprintf(stderr, "failed to update PIC1 state: %d\n", ret);
71         return 1;
72     }
73 
74     ret = crosvm_get_ioapic_state(crosvm, &ioapic_state);
75     if (ret < 0) {
76         fprintf(stderr, "failed to get updated PIC1 state: %d\n", ret);
77         return 1;
78     }
79 
80     if (ioapic_state.id != 1) {
81         fprintf(stderr, "unexpected value of IOAPIC ID after update: %d\n",
82                 ioapic_state.id);
83         return 1;
84     }
85 
86     // Test retrieving and setting PIT state.
87     struct kvm_pit_state2 pit_state;
88     ret = crosvm_get_pit_state(crosvm, &pit_state);
89     if (ret < 0) {
90         fprintf(stderr, "failed to get initial PIT state: %d\n", ret);
91         return 1;
92     }
93 
94     if (pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY) {
95         fprintf(stderr, "unexpected value of KVM_PIT_FLAGS_HPET_LEGACY flag\n");
96         return 1;
97     }
98 
99     pit_state.flags |= KVM_PIT_FLAGS_HPET_LEGACY;
100     ret = crosvm_set_pit_state(crosvm, &pit_state);
101     if (ret < 0) {
102         fprintf(stderr, "failed to update PIT state: %d\n", ret);
103         return 1;
104     }
105 
106     ret = crosvm_get_pit_state(crosvm, &pit_state);
107     if (ret < 0) {
108         fprintf(stderr, "failed to get updated PIT state: %d\n", ret);
109         return 1;
110     }
111 
112     if (!(pit_state.flags & KVM_PIT_FLAGS_HPET_LEGACY)) {
113         fprintf(stderr,
114                 "unexpected value of KVM_PIT_FLAGS_HPET_LEGACY after update\n");
115         return 1;
116     }
117 
118     // Test retrieving and setting clock state.
119     struct kvm_clock_data clock_data = { .clock = 0, .flags = -1U, };
120     ret = crosvm_get_clock(crosvm, &clock_data);
121     if (ret < 0) {
122         fprintf(stderr, "failed to get initial clock state: %d\n", ret);
123         return 1;
124     }
125 
126     if (clock_data.clock == 0 || clock_data.flags != 0) {
127         fprintf(stderr, "invalid clock data returned (%llu, %u)\n",
128                 clock_data.clock, clock_data.flags);
129     }
130 
131     clock_data.clock += 10000000;
132 
133     ret = crosvm_set_clock(crosvm, &clock_data);
134     if (ret < 0) {
135         fprintf(stderr, "failed to update clock: %d\n", ret);
136         return 1;
137     }
138 
139     clock_data.flags = -1U;
140     ret = crosvm_set_clock(crosvm, &clock_data);
141     if (ret >= 0) {
142         fprintf(stderr, "unexpected success updating clock\n");
143         return 1;
144     }
145 
146     return 0;
147 }
148