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