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