Compile with -Wreturn-type
[akaros.git] / user / vmm / decode.c
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * This file is part of Akaros.
5  *
6  * Akarosn is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, version 2 of the License.
9  *
10  * Akaros is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * Lesser GNU General Public License for more details.
14  *
15  * See COPYING.LESSER for details on the GNU Lesser General Public License.
16  * See COPYING for details on the GNU General Public License.
17  */
18
19 #include <stdio.h>
20 #include <sys/types.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <parlib/arch/arch.h>
25 #include <parlib/ros_debug.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/uio.h>
31 #include <stdint.h>
32 #include <err.h>
33 #include <sys/mman.h>
34 #include <vmm/vmm.h>
35 #include <vmm/virtio.h>
36 #include <vmm/virtio_mmio.h>
37 #include <vmm/virtio_ids.h>
38 #include <vmm/virtio_config.h>
39 #include <ros/arch/mmu.h>
40 #include <ros/arch/trapframe.h>
41
42 int debug_decode = 0;
43 #define DPRINTF(fmt, ...) \
44         do { \
45                 if (debug_decode) { \
46                         fprintf(stderr, "decode: " fmt, ## __VA_ARGS__); \
47                 } \
48         } \
49         while (0)
50
51 static char *modrmreg[] = {"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"};
52
53 // Since we at most have to decode less than half of each instruction, I'm trying to be dumb here.
54 // Fortunately, for me, that's not hard.
55 // I'm trying to avoid the whole Big Fun of full instruction decode, and in most of these
56 // cases we only have to know register, address, operation size, and instruction length.
57 // The ugly messiness of the SIB and all that are not yet needed. Maybe they
58 // never will be.
59
60 // Target size -- 1, 2, 4, or 8 bytes. We have yet to see 64 bytes.
61 // TODO: if we ever see it, test the prefix. Since this only supports the low 1M,
62 // that's not likely.
63 static int target(void *insn, int *store)
64 {
65         *store = 0;
66         int s = -1;
67         uint8_t *byte = insn;
68         uint16_t *word = insn;
69
70         if (*byte == 0x66) {
71                 s = target(insn+1,store);
72                 // flip the sense of s.
73                 s = s == 4 ? 2 : 4;
74                 return s;
75         }
76         if (*byte == 0x44) {
77                 byte++;
78                 word++;
79         }
80         switch(*byte) {
81         case 0x3a:
82         case 0x8a:
83         case 0x88:
84                 s = 1;
85                 break;
86         case 0x89:
87         case 0x8b:
88                 // TODO: To really know, for sure, that this is 32 bit, we'd likely have
89                 //       to check the segment descriptor for the guest's current code
90                 //       segment in it's GDT. The D flag (bit 22) determines whether the
91                 //       instruction is using 32 or 16-bit operand size. I'm just going
92                 //       to assume the flag is set (meaning 32 bit operands) for now, in
93                 //       order to make virtio work. But really we should check if we
94                 //       want to know for sure. Note that this hack (changing the below
95                 //       line) only applies to mov instructions.
96                 //
97                 //       And I think there's also a prefix you can use to switch the
98                 //       instruction to 16-bit addressing
99                 //       (address-size override prefix?)
100                 s = 4;
101                 break;
102         case 0x81:
103                 s = 4;
104                 break;
105         case 0x0f:
106                 switch (*word) {
107                         case 0xb70f:
108                                 s = 2;
109                                 break;
110                         default:
111                                 fprintf(stderr, "can't get size of %02x/%04x @ %p\n", *byte,
112                                         *word, byte);
113                                 return -1;
114                 }
115                 break;
116         case 0x41:
117                 /* VEX byte for modrm field */
118                 switch (*word) {
119                         case 0x8a41:
120                                 s = 1;
121                                 break;
122                         default:
123                                 fprintf(stderr, "unparsed vex instruction %02x/%04x @ %p\n",
124                                         *byte, *word, byte);
125                                 return -1;
126                 }
127                 break;
128         default:
129                 fprintf(stderr, "can't get size of %02x @ %p\n", *byte, byte);
130                 fprintf(stderr, "can't get WORD of %04x @ %p\n", *word, word);
131                 return -1;
132                 break;
133         }
134
135         switch(*byte) {
136         case 0x0f:
137         case 0x41:
138                 break;
139         case 0x3a:
140         case 0x8a:
141         case 0x88:
142         case 0x89:
143         case 0x8b:
144         case 0x81:
145                 *store = !(*byte & 2);
146                 break;
147         default:
148                 fprintf(stderr, "%s: Can't happen. rip is: %p\n", __func__, byte);
149                 break;
150         }
151         return s;
152 }
153
154 char *regname(uint8_t reg)
155 {
156         return modrmreg[reg];
157 }
158
159 static int insize(void *rip)
160 {
161         uint8_t *rip_gpa = rip;
162         int advance = 3;
163         int extra = 0;
164         if (rip_gpa[0] == 0x44) {
165                 extra = 1;
166                 rip_gpa++;
167         }
168
169         /* return 3 to handle this specific instruction case. We don't want this
170          * to turn into a fully fledged decode.
171          * This specific instruction is an extended move using r9. It uses the
172          * VEX byte to extend the register bits. */
173         if (rip_gpa[0] == 0x41 && rip_gpa[1] == 0x8a && rip_gpa[2] == 0x01)
174                 return 3;
175         /* the dreaded mod/rm byte. */
176         int mod = rip_gpa[1] >> 6;
177         int rm = rip_gpa[1] & 7;
178
179         switch (rip_gpa[0]) {
180         default:
181                 fprintf(stderr, "BUG! %s got 0x%x\n", __func__, rip_gpa[0]);
182         case 0x0f:
183                 break;
184         case 0x81:
185                 advance = 6 + extra;
186                 break;
187         case 0x3a:
188         case 0x8a:
189         case 0x88:
190         case 0x89:
191         case 0x8b:
192                 switch (mod) {
193                 case 0:
194                         advance = 2 + (rm == 4) + extra;
195                         break;
196                 case 1:
197                         advance = 3 + (rm == 4) + extra;
198                         break;
199                 case 2:
200                         advance = 6 + (rm == 4) + extra;
201                         break;
202                 case 3:
203                         advance = 2 + extra;
204                         break;
205                 }
206                 break;
207         }
208         return advance;
209 }
210
211 // This is a very limited function. It's only here to manage virtio-mmio and low memory
212 // pointer loads. I am hoping it won't grow with time. The intent is that we enter it with
213 // and EPT fault from a region that is deliberately left unbacked by any memory. We return
214 // enough info to let you emulate the operation if you want. Because we have the failing physical
215 // address (gpa) the decode is far simpler because we only need to find the register, how many bytes
216 // to move, and how big the instruction is. I thought about bringing in emulate.c from kvm from xen,
217 // but it has way more stuff than we need.
218 // gpa is a pointer to the gpa.
219 // int is the reg index which we can use for printing info.
220 // regp points to the register in hw_trapframe from which
221 // to load or store a result.
222 int decode(struct guest_thread *vm_thread, uint64_t *gpa, uint8_t *destreg,
223            uint64_t **regp, int *store, int *size, int *advance)
224 {
225         struct vm_trapframe *vm_tf = &(vm_thread->uthread.u_ctx.tf.vm_tf);
226         uint8_t *rip_gpa = NULL;
227
228         DPRINTF("v is %p\n", vm_tf);
229
230         // Duh, which way did he go George? Which way did he go?
231         // First hit on Google gets you there!
232         // This is the guest physical address of the access.
233         // This is nice, because if we ever go with more complete
234         // instruction decode, knowing this gpa reduces our work:
235         // we don't have to find the source address in registers,
236         // only the register holding or receiving the value.
237         *gpa = vm_tf->tf_guest_pa;
238         DPRINTF("gpa is %p\n", *gpa);
239
240         DPRINTF("rip is %p\n", vm_tf->tf_rip);
241
242         if (rippa(vm_thread, (uint64_t *)&rip_gpa))
243                 return VM_PAGE_FAULT;
244         DPRINTF("rip_gpa is %p\n", rip_gpa);
245
246         // fail fast. If we can't get the size we're done.
247         *size = target(rip_gpa, store);
248         DPRINTF("store is %d\n", *store);
249         if (*size < 0)
250                 return -1;
251
252         *advance = insize(rip_gpa);
253
254         uint16_t ins = *(uint16_t *)(rip_gpa +
255             ((rip_gpa[0] == 0x44) || (rip_gpa[0] == 0x0f) || (rip_gpa[0] == 0x41)));
256
257         DPRINTF("ins is %04x\n", ins);
258
259         *destreg = (ins>>11) & 7;
260         *destreg += 8 * (rip_gpa[0] == 0x44);
261         // Our primitive approach wins big here.
262         // We don't have to decode the register or the offset used
263         // in the computation; that was done by the CPU and is the gpa.
264         // All we need to know is which destination or source register it is.
265         switch (*destreg) {
266         case 0:
267                 *regp = &vm_tf->tf_rax;
268                 break;
269         case 1:
270                 *regp = &vm_tf->tf_rcx;
271                 break;
272         case 2:
273                 *regp = &vm_tf->tf_rdx;
274                 break;
275         case 3:
276                 *regp = &vm_tf->tf_rbx;
277                 break;
278         case 4:
279                 *regp = &vm_tf->tf_rsp; // uh, right.
280                 break;
281         case 5:
282                 *regp = &vm_tf->tf_rbp;
283                 break;
284         case 6:
285                 *regp = &vm_tf->tf_rsi;
286                 break;
287         case 7:
288                 *regp = &vm_tf->tf_rdi;
289                 break;
290         case 8:
291                 *regp = &vm_tf->tf_r8;
292                 break;
293         case 9:
294                 *regp = &vm_tf->tf_r9;
295                 break;
296         case 10:
297                 *regp = &vm_tf->tf_r10;
298                 break;
299         case 11:
300                 *regp = &vm_tf->tf_r11;
301                 break;
302         case 12:
303                 *regp = &vm_tf->tf_r12;
304                 break;
305         case 13:
306                 *regp = &vm_tf->tf_r13;
307                 break;
308         case 14:
309                 *regp = &vm_tf->tf_r14;
310                 break;
311         case 15:
312                 *regp = &vm_tf->tf_r15;
313                 break;
314         }
315         return 0;
316 }