ia64/xen-unstable

view xen/arch/x86/vmx_platform.c @ 8492:9fc306e40a7c

Move public hvm interfaces into xen/include/public/hvm.
Add new header hvm_info_table.h for defining location and
contents of acpi-style hvm_info_table. Remove duplicate
definition in vmxassist/acpi_madt.c.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Tue Jan 03 14:58:34 2006 +0100 (2006-01-03)
parents eaee11008e68
children
line source
1 /*
2 * vmx_platform.c: handling x86 platform related MMIO instructions
3 * Copyright (c) 2004, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 */
20 #include <xen/config.h>
21 #include <xen/types.h>
22 #include <xen/mm.h>
23 #include <asm/shadow.h>
24 #include <xen/domain_page.h>
25 #include <asm/page.h>
26 #include <xen/event.h>
27 #include <xen/trace.h>
28 #include <asm/vmx.h>
29 #include <asm/vmx_platform.h>
30 #include <public/hvm/ioreq.h>
32 #include <xen/lib.h>
33 #include <xen/sched.h>
34 #include <asm/current.h>
35 #if CONFIG_PAGING_LEVELS >= 3
36 #include <asm/shadow_64.h>
37 #endif
38 #ifdef CONFIG_VMX
40 #define DECODE_success 1
41 #define DECODE_failure 0
43 #if defined (__x86_64__)
44 void store_cpu_user_regs(struct cpu_user_regs *regs)
45 {
46 __vmread(GUEST_SS_SELECTOR, &regs->ss);
47 __vmread(GUEST_RSP, &regs->rsp);
48 __vmread(GUEST_RFLAGS, &regs->rflags);
49 __vmread(GUEST_CS_SELECTOR, &regs->cs);
50 __vmread(GUEST_DS_SELECTOR, &regs->ds);
51 __vmread(GUEST_ES_SELECTOR, &regs->es);
52 __vmread(GUEST_RIP, &regs->rip);
53 }
55 static inline long __get_reg_value(unsigned long reg, int size)
56 {
57 switch(size) {
58 case BYTE_64:
59 return (char)(reg & 0xFF);
60 case WORD:
61 return (short)(reg & 0xFFFF);
62 case LONG:
63 return (int)(reg & 0xFFFFFFFF);
64 case QUAD:
65 return (long)(reg);
66 default:
67 printf("Error: (__get_reg_value) Invalid reg size\n");
68 domain_crash_synchronous();
69 }
70 }
72 long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
73 {
74 if (size == BYTE) {
75 switch (index) {
76 case 0: /* %al */
77 return (char)(regs->rax & 0xFF);
78 case 1: /* %cl */
79 return (char)(regs->rcx & 0xFF);
80 case 2: /* %dl */
81 return (char)(regs->rdx & 0xFF);
82 case 3: /* %bl */
83 return (char)(regs->rbx & 0xFF);
84 case 4: /* %ah */
85 return (char)((regs->rax & 0xFF00) >> 8);
86 case 5: /* %ch */
87 return (char)((regs->rcx & 0xFF00) >> 8);
88 case 6: /* %dh */
89 return (char)((regs->rdx & 0xFF00) >> 8);
90 case 7: /* %bh */
91 return (char)((regs->rbx & 0xFF00) >> 8);
92 default:
93 printf("Error: (get_reg_value) Invalid index value\n");
94 domain_crash_synchronous();
95 }
96 /* NOTREACHED */
97 }
99 switch (index) {
100 case 0: return __get_reg_value(regs->rax, size);
101 case 1: return __get_reg_value(regs->rcx, size);
102 case 2: return __get_reg_value(regs->rdx, size);
103 case 3: return __get_reg_value(regs->rbx, size);
104 case 4: return __get_reg_value(regs->rsp, size);
105 case 5: return __get_reg_value(regs->rbp, size);
106 case 6: return __get_reg_value(regs->rsi, size);
107 case 7: return __get_reg_value(regs->rdi, size);
108 case 8: return __get_reg_value(regs->r8, size);
109 case 9: return __get_reg_value(regs->r9, size);
110 case 10: return __get_reg_value(regs->r10, size);
111 case 11: return __get_reg_value(regs->r11, size);
112 case 12: return __get_reg_value(regs->r12, size);
113 case 13: return __get_reg_value(regs->r13, size);
114 case 14: return __get_reg_value(regs->r14, size);
115 case 15: return __get_reg_value(regs->r15, size);
116 default:
117 printf("Error: (get_reg_value) Invalid index value\n");
118 domain_crash_synchronous();
119 }
120 }
121 #elif defined (__i386__)
122 void store_cpu_user_regs(struct cpu_user_regs *regs)
123 {
124 __vmread(GUEST_SS_SELECTOR, &regs->ss);
125 __vmread(GUEST_RSP, &regs->esp);
126 __vmread(GUEST_RFLAGS, &regs->eflags);
127 __vmread(GUEST_CS_SELECTOR, &regs->cs);
128 __vmread(GUEST_DS_SELECTOR, &regs->ds);
129 __vmread(GUEST_ES_SELECTOR, &regs->es);
130 __vmread(GUEST_RIP, &regs->eip);
131 }
133 static inline long __get_reg_value(unsigned long reg, int size)
134 {
135 switch(size) {
136 case WORD:
137 return (short)(reg & 0xFFFF);
138 case LONG:
139 return (int)(reg & 0xFFFFFFFF);
140 default:
141 printf("Error: (__get_reg_value) Invalid reg size\n");
142 domain_crash_synchronous();
143 }
144 }
146 long get_reg_value(int size, int index, int seg, struct cpu_user_regs *regs)
147 {
148 if (size == BYTE) {
149 switch (index) {
150 case 0: /* %al */
151 return (char)(regs->eax & 0xFF);
152 case 1: /* %cl */
153 return (char)(regs->ecx & 0xFF);
154 case 2: /* %dl */
155 return (char)(regs->edx & 0xFF);
156 case 3: /* %bl */
157 return (char)(regs->ebx & 0xFF);
158 case 4: /* %ah */
159 return (char)((regs->eax & 0xFF00) >> 8);
160 case 5: /* %ch */
161 return (char)((regs->ecx & 0xFF00) >> 8);
162 case 6: /* %dh */
163 return (char)((regs->edx & 0xFF00) >> 8);
164 case 7: /* %bh */
165 return (char)((regs->ebx & 0xFF00) >> 8);
166 default:
167 printf("Error: (get_reg_value) Invalid index value\n");
168 domain_crash_synchronous();
169 }
170 }
172 switch (index) {
173 case 0: return __get_reg_value(regs->eax, size);
174 case 1: return __get_reg_value(regs->ecx, size);
175 case 2: return __get_reg_value(regs->edx, size);
176 case 3: return __get_reg_value(regs->ebx, size);
177 case 4: return __get_reg_value(regs->esp, size);
178 case 5: return __get_reg_value(regs->ebp, size);
179 case 6: return __get_reg_value(regs->esi, size);
180 case 7: return __get_reg_value(regs->edi, size);
181 default:
182 printf("Error: (get_reg_value) Invalid index value\n");
183 domain_crash_synchronous();
184 }
185 }
186 #endif
188 static inline unsigned char *check_prefix(unsigned char *inst,
189 struct instruction *thread_inst, unsigned char *rex_p)
190 {
191 while (1) {
192 switch (*inst) {
193 /* rex prefix for em64t instructions */
194 case 0x40 ... 0x4e:
195 *rex_p = *inst;
196 break;
197 case 0xf3: /* REPZ */
198 thread_inst->flags = REPZ;
199 break;
200 case 0xf2: /* REPNZ */
201 thread_inst->flags = REPNZ;
202 break;
203 case 0xf0: /* LOCK */
204 break;
205 case 0x2e: /* CS */
206 case 0x36: /* SS */
207 case 0x3e: /* DS */
208 case 0x26: /* ES */
209 case 0x64: /* FS */
210 case 0x65: /* GS */
211 thread_inst->seg_sel = *inst;
212 break;
213 case 0x66: /* 32bit->16bit */
214 thread_inst->op_size = WORD;
215 break;
216 case 0x67:
217 printf("Error: Not handling 0x67 (yet)\n");
218 domain_crash_synchronous();
219 break;
220 default:
221 return inst;
222 }
223 inst++;
224 }
225 }
227 static inline unsigned long get_immediate(int op16,const unsigned char *inst, int op_size)
228 {
229 int mod, reg, rm;
230 unsigned long val = 0;
231 int i;
233 mod = (*inst >> 6) & 3;
234 reg = (*inst >> 3) & 7;
235 rm = *inst & 7;
237 inst++; //skip ModR/M byte
238 if (mod != 3 && rm == 4) {
239 inst++; //skip SIB byte
240 }
242 switch(mod) {
243 case 0:
244 if (rm == 5 || rm == 4) {
245 if (op16)
246 inst = inst + 2; //disp16, skip 2 bytes
247 else
248 inst = inst + 4; //disp32, skip 4 bytes
249 }
250 break;
251 case 1:
252 inst++; //disp8, skip 1 byte
253 break;
254 case 2:
255 if (op16)
256 inst = inst + 2; //disp16, skip 2 bytes
257 else
258 inst = inst + 4; //disp32, skip 4 bytes
259 break;
260 }
262 if (op_size == QUAD)
263 op_size = LONG;
265 for (i = 0; i < op_size; i++) {
266 val |= (*inst++ & 0xff) << (8 * i);
267 }
269 return val;
270 }
272 static inline int get_index(const unsigned char *inst, unsigned char rex)
273 {
274 int mod, reg, rm;
275 int rex_r, rex_b;
277 mod = (*inst >> 6) & 3;
278 reg = (*inst >> 3) & 7;
279 rm = *inst & 7;
281 rex_r = (rex >> 2) & 1;
282 rex_b = rex & 1;
284 //Only one operand in the instruction is register
285 if (mod == 3) {
286 return (rm + (rex_b << 3));
287 } else {
288 return (reg + (rex_r << 3));
289 }
290 return 0;
291 }
293 static void init_instruction(struct instruction *mmio_inst)
294 {
295 mmio_inst->instr = 0;
296 mmio_inst->op_size = 0;
297 mmio_inst->immediate = 0;
298 mmio_inst->seg_sel = 0;
300 mmio_inst->operand[0] = 0;
301 mmio_inst->operand[1] = 0;
303 mmio_inst->flags = 0;
304 }
306 #define GET_OP_SIZE_FOR_BYTE(op_size) \
307 do { \
308 if (rex) \
309 op_size = BYTE_64; \
310 else \
311 op_size = BYTE; \
312 } while(0)
314 #define GET_OP_SIZE_FOR_NONEBYTE(op_size) \
315 do { \
316 if (rex & 0x8) \
317 op_size = QUAD; \
318 else if (op_size != WORD) \
319 op_size = LONG; \
320 } while(0)
323 /*
324 * Decode mem,accumulator operands (as in <opcode> m8/m16/m32, al,ax,eax)
325 */
326 static int mem_acc(unsigned char size, struct instruction *instr)
327 {
328 instr->operand[0] = mk_operand(size, 0, 0, MEMORY);
329 instr->operand[1] = mk_operand(size, 0, 0, REGISTER);
330 return DECODE_success;
331 }
333 /*
334 * Decode accumulator,mem operands (as in <opcode> al,ax,eax, m8/m16/m32)
335 */
336 static int acc_mem(unsigned char size, struct instruction *instr)
337 {
338 instr->operand[0] = mk_operand(size, 0, 0, REGISTER);
339 instr->operand[1] = mk_operand(size, 0, 0, MEMORY);
340 return DECODE_success;
341 }
343 /*
344 * Decode mem,reg operands (as in <opcode> r32/16, m32/16)
345 */
346 static int mem_reg(unsigned char size, unsigned char *opcode,
347 struct instruction *instr, unsigned char rex)
348 {
349 int index = get_index(opcode + 1, rex);
351 instr->operand[0] = mk_operand(size, 0, 0, MEMORY);
352 instr->operand[1] = mk_operand(size, index, 0, REGISTER);
353 return DECODE_success;
354 }
356 /*
357 * Decode reg,mem operands (as in <opcode> m32/16, r32/16)
358 */
359 static int reg_mem(unsigned char size, unsigned char *opcode,
360 struct instruction *instr, unsigned char rex)
361 {
362 int index = get_index(opcode + 1, rex);
364 instr->operand[0] = mk_operand(size, index, 0, REGISTER);
365 instr->operand[1] = mk_operand(size, 0, 0, MEMORY);
366 return DECODE_success;
367 }
369 static int vmx_decode(int vm86, unsigned char *opcode, struct instruction *instr)
370 {
371 unsigned char size_reg = 0;
372 unsigned char rex = 0;
373 int index;
375 init_instruction(instr);
377 opcode = check_prefix(opcode, instr, &rex);
379 if (vm86) { /* meaning is reversed */
380 if (instr->op_size == WORD)
381 instr->op_size = LONG;
382 else if (instr->op_size == LONG)
383 instr->op_size = WORD;
384 else if (instr->op_size == 0)
385 instr->op_size = WORD;
386 }
388 switch (*opcode) {
389 case 0x0B: /* or m32/16, r32/16 */
390 instr->instr = INSTR_OR;
391 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
392 return mem_reg(instr->op_size, opcode, instr, rex);
394 case 0x20: /* and r8, m8 */
395 instr->instr = INSTR_AND;
396 instr->op_size = BYTE;
397 GET_OP_SIZE_FOR_BYTE(size_reg);
398 return reg_mem(size_reg, opcode, instr, rex);
400 case 0x21: /* and r32/16, m32/16 */
401 instr->instr = INSTR_AND;
402 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
403 return reg_mem(instr->op_size, opcode, instr, rex);
405 case 0x23: /* and m32/16, r32/16 */
406 instr->instr = INSTR_AND;
407 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
408 return mem_reg(instr->op_size, opcode, instr, rex);
410 case 0x30: /* xor r8, m8 */
411 instr->instr = INSTR_XOR;
412 instr->op_size = BYTE;
413 GET_OP_SIZE_FOR_BYTE(size_reg);
414 return reg_mem(size_reg, opcode, instr, rex);
416 case 0x31: /* xor r32/16, m32/16 */
417 instr->instr = INSTR_XOR;
418 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
419 return reg_mem(instr->op_size, opcode, instr, rex);
421 case 0x39: /* cmp r32/16, m32/16 */
422 instr->instr = INSTR_CMP;
423 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
424 return reg_mem(instr->op_size, opcode, instr, rex);
426 case 0x80:
427 case 0x81:
428 {
429 unsigned char ins_subtype = (opcode[1] >> 3) & 7;
431 if (opcode[0] == 0x80) {
432 GET_OP_SIZE_FOR_BYTE(size_reg);
433 instr->op_size = BYTE;
434 } else {
435 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
436 size_reg = instr->op_size;
437 }
439 instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
440 instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
441 instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
443 switch (ins_subtype) {
444 case 7: /* cmp $imm, m32/16 */
445 instr->instr = INSTR_CMP;
446 return DECODE_success;
448 case 1: /* or $imm, m32/16 */
449 instr->instr = INSTR_OR;
450 return DECODE_success;
452 default:
453 printf("%x, This opcode isn't handled yet!\n", *opcode);
454 return DECODE_failure;
455 }
456 }
458 case 0x84: /* test m8, r8 */
459 instr->instr = INSTR_TEST;
460 instr->op_size = BYTE;
461 GET_OP_SIZE_FOR_BYTE(size_reg);
462 return mem_reg(size_reg, opcode, instr, rex);
464 case 0x88: /* mov r8, m8 */
465 instr->instr = INSTR_MOV;
466 instr->op_size = BYTE;
467 GET_OP_SIZE_FOR_BYTE(size_reg);
468 return reg_mem(size_reg, opcode, instr, rex);
470 case 0x89: /* mov r32/16, m32/16 */
471 instr->instr = INSTR_MOV;
472 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
473 return reg_mem(instr->op_size, opcode, instr, rex);
475 case 0x8A: /* mov m8, r8 */
476 instr->instr = INSTR_MOV;
477 instr->op_size = BYTE;
478 GET_OP_SIZE_FOR_BYTE(size_reg);
479 return mem_reg(size_reg, opcode, instr, rex);
481 case 0x8B: /* mov m32/16, r32/16 */
482 instr->instr = INSTR_MOV;
483 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
484 return mem_reg(instr->op_size, opcode, instr, rex);
486 case 0xA0: /* mov <addr>, al */
487 instr->instr = INSTR_MOV;
488 instr->op_size = BYTE;
489 GET_OP_SIZE_FOR_BYTE(size_reg);
490 return mem_acc(size_reg, instr);
492 case 0xA1: /* mov <addr>, ax/eax */
493 instr->instr = INSTR_MOV;
494 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
495 return mem_acc(instr->op_size, instr);
497 case 0xA2: /* mov al, <addr> */
498 instr->instr = INSTR_MOV;
499 instr->op_size = BYTE;
500 GET_OP_SIZE_FOR_BYTE(size_reg);
501 return acc_mem(size_reg, instr);
503 case 0xA3: /* mov ax/eax, <addr> */
504 instr->instr = INSTR_MOV;
505 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
506 return acc_mem(instr->op_size, instr);
508 case 0xA4: /* movsb */
509 instr->instr = INSTR_MOVS;
510 instr->op_size = BYTE;
511 return DECODE_success;
513 case 0xA5: /* movsw/movsl */
514 instr->instr = INSTR_MOVS;
515 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
516 return DECODE_success;
518 case 0xAA: /* stosb */
519 instr->instr = INSTR_STOS;
520 instr->op_size = BYTE;
521 return DECODE_success;
523 case 0xAB: /* stosw/stosl */
524 instr->instr = INSTR_STOS;
525 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
526 return DECODE_success;
528 case 0xC6:
529 if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm8, m8 */
530 instr->instr = INSTR_MOV;
531 instr->op_size = BYTE;
533 instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
534 instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
535 instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
537 return DECODE_success;
538 } else
539 return DECODE_failure;
541 case 0xC7:
542 if (((opcode[1] >> 3) & 7) == 0) { /* mov $imm16/32, m16/32 */
543 instr->instr = INSTR_MOV;
544 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
546 instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE);
547 instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
548 instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
550 return DECODE_success;
551 } else
552 return DECODE_failure;
554 case 0xF6:
555 case 0xF7:
556 if (((opcode[1] >> 3) & 7) == 0) { /* test $imm8/16/32, m8/16/32 */
557 instr->instr = INSTR_TEST;
559 if (opcode[0] == 0xF6) {
560 GET_OP_SIZE_FOR_BYTE(size_reg);
561 instr->op_size = BYTE;
562 } else {
563 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
564 size_reg = instr->op_size;
565 }
567 instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
568 instr->immediate = get_immediate(vm86, opcode+1, instr->op_size);
569 instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
571 return DECODE_success;
572 } else
573 return DECODE_failure;
575 case 0x0F:
576 break;
578 default:
579 printf("%x, This opcode isn't handled yet!\n", *opcode);
580 return DECODE_failure;
581 }
583 switch (*++opcode) {
584 case 0xB6: /* movzx m8, r16/r32/r64 */
585 instr->instr = INSTR_MOVZX;
586 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
587 index = get_index(opcode + 1, rex);
588 instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
589 instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
590 return DECODE_success;
592 case 0xB7: /* movzx m16/m32, r32/r64 */
593 instr->instr = INSTR_MOVZX;
594 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
595 index = get_index(opcode + 1, rex);
596 if (rex & 0x8)
597 instr->operand[0] = mk_operand(LONG, 0, 0, MEMORY);
598 else
599 instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
600 instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
601 return DECODE_success;
603 case 0xBE: /* movsx m8, r16/r32/r64 */
604 instr->instr = INSTR_MOVSX;
605 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
606 index = get_index(opcode + 1, rex);
607 instr->operand[0] = mk_operand(BYTE, 0, 0, MEMORY);
608 instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
609 return DECODE_success;
611 case 0xBF: /* movsx m16, r32/r64 */
612 instr->instr = INSTR_MOVSX;
613 GET_OP_SIZE_FOR_NONEBYTE(instr->op_size);
614 index = get_index(opcode + 1, rex);
615 instr->operand[0] = mk_operand(WORD, 0, 0, MEMORY);
616 instr->operand[1] = mk_operand(instr->op_size, index, 0, REGISTER);
617 return DECODE_success;
619 case 0xA3: /* bt r32, m32 */
620 instr->instr = INSTR_BT;
621 index = get_index(opcode + 1, rex);
622 instr->op_size = LONG;
623 instr->operand[0] = mk_operand(instr->op_size, index, 0, REGISTER);
624 instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY);
625 return DECODE_success;
627 default:
628 printf("0f %x, This opcode isn't handled yet\n", *opcode);
629 return DECODE_failure;
630 }
631 }
633 int inst_copy_from_guest(unsigned char *buf, unsigned long guest_eip, int inst_len)
634 {
635 if (inst_len > MAX_INST_LEN || inst_len <= 0)
636 return 0;
637 if (!vmx_copy(buf, guest_eip, inst_len, VMX_COPY_IN))
638 return 0;
639 return inst_len;
640 }
642 void send_mmio_req(unsigned char type, unsigned long gpa,
643 unsigned long count, int size, long value, int dir, int pvalid)
644 {
645 struct vcpu *v = current;
646 vcpu_iodata_t *vio;
647 ioreq_t *p;
648 struct cpu_user_regs *regs;
649 extern long evtchn_send(int lport);
651 regs = current->arch.arch_vmx.mmio_op.inst_decoder_regs;
653 vio = get_vio(v->domain, v->vcpu_id);
654 if (vio == NULL) {
655 printf("bad shared page\n");
656 domain_crash_synchronous();
657 }
659 p = &vio->vp_ioreq;
661 if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
662 printf("VMX I/O has not yet completed\n");
663 domain_crash_synchronous();
664 }
666 set_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
667 p->dir = dir;
668 p->pdata_valid = pvalid;
670 p->type = type;
671 p->size = size;
672 p->addr = gpa;
673 p->count = count;
674 p->df = regs->eflags & EF_DF ? 1 : 0;
676 if (pvalid) {
677 if (vmx_paging_enabled(current))
678 p->u.pdata = (void *) gva_to_gpa(value);
679 else
680 p->u.pdata = (void *) value; /* guest VA == guest PA */
681 } else
682 p->u.data = value;
684 if (vmx_mmio_intercept(p)){
685 p->state = STATE_IORESP_READY;
686 vmx_io_assist(v);
687 return;
688 }
690 p->state = STATE_IOREQ_READY;
692 evtchn_send(iopacket_port(v->domain));
693 vmx_wait_io();
694 }
696 static void mmio_operands(int type, unsigned long gpa, struct instruction *inst,
697 struct mmio_op *mmio_opp, struct cpu_user_regs *regs)
698 {
699 unsigned long value = 0;
700 int index, size_reg;
702 size_reg = operand_size(inst->operand[0]);
704 mmio_opp->flags = inst->flags;
705 mmio_opp->instr = inst->instr;
706 mmio_opp->operand[0] = inst->operand[0]; /* source */
707 mmio_opp->operand[1] = inst->operand[1]; /* destination */
708 mmio_opp->immediate = inst->immediate;
710 if (inst->operand[0] & REGISTER) { /* dest is memory */
711 index = operand_index(inst->operand[0]);
712 value = get_reg_value(size_reg, index, 0, regs);
713 send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
714 } else if (inst->operand[0] & IMMEDIATE) { /* dest is memory */
715 value = inst->immediate;
716 send_mmio_req(type, gpa, 1, inst->op_size, value, IOREQ_WRITE, 0);
717 } else if (inst->operand[0] & MEMORY) { /* dest is register */
718 /* send the request and wait for the value */
719 if ( (inst->instr == INSTR_MOVZX) || (inst->instr == INSTR_MOVSX) )
720 send_mmio_req(type, gpa, 1, size_reg, 0, IOREQ_READ, 0);
721 else
722 send_mmio_req(type, gpa, 1, inst->op_size, 0, IOREQ_READ, 0);
723 } else {
724 printf("mmio_operands: invalid operand\n");
725 domain_crash_synchronous();
726 }
727 }
729 #define GET_REPEAT_COUNT() \
730 (mmio_inst.flags & REPZ ? (vm86 ? regs->ecx & 0xFFFF : regs->ecx) : 1)
732 void handle_mmio(unsigned long va, unsigned long gpa)
733 {
734 unsigned long inst_len, inst_addr;
735 struct mmio_op *mmio_opp;
736 struct cpu_user_regs *regs;
737 struct instruction mmio_inst;
738 unsigned char inst[MAX_INST_LEN];
739 int i, vm86, ret;
741 mmio_opp = &current->arch.arch_vmx.mmio_op;
743 regs = mmio_opp->inst_decoder_regs;
744 store_cpu_user_regs(regs);
746 __vmread(VM_EXIT_INSTRUCTION_LEN, &inst_len);
748 vm86 = regs->eflags & X86_EFLAGS_VM;
749 if (vm86)
750 inst_addr = (regs->cs << 4) + regs->eip;
751 else
752 inst_addr = regs->eip;
754 memset(inst, 0, MAX_INST_LEN);
755 ret = inst_copy_from_guest(inst, inst_addr, inst_len);
756 if (ret != inst_len) {
757 printf("handle_mmio - EXIT: get guest instruction fault\n");
758 domain_crash_synchronous();
759 }
761 init_instruction(&mmio_inst);
763 if (vmx_decode(vm86, inst, &mmio_inst) == DECODE_failure) {
764 printf("mmio opcode: va 0x%lx, gpa 0x%lx, len %ld:",
765 va, gpa, inst_len);
766 for (i = 0; i < inst_len; i++)
767 printf(" %02x", inst[i] & 0xFF);
768 printf("\n");
769 domain_crash_synchronous();
770 }
772 regs->eip += inst_len; /* advance %eip */
774 switch (mmio_inst.instr) {
775 case INSTR_MOV:
776 mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
777 break;
779 case INSTR_MOVS:
780 {
781 unsigned long count = GET_REPEAT_COUNT();
782 unsigned long size = mmio_inst.op_size;
783 int sign = regs->eflags & EF_DF ? -1 : 1;
784 unsigned long addr = 0;
785 int dir;
787 /* determine non-MMIO address */
788 if (vm86) {
789 if (((regs->es << 4) + (regs->edi & 0xFFFF)) == va) {
790 dir = IOREQ_WRITE;
791 addr = (regs->ds << 4) + (regs->esi & 0xFFFF);
792 } else {
793 dir = IOREQ_READ;
794 addr = (regs->es << 4) + (regs->edi & 0xFFFF);
795 }
796 } else {
797 if (va == regs->edi) {
798 dir = IOREQ_WRITE;
799 addr = regs->esi;
800 } else {
801 dir = IOREQ_READ;
802 addr = regs->edi;
803 }
804 }
806 mmio_opp->flags = mmio_inst.flags;
807 mmio_opp->instr = mmio_inst.instr;
809 /*
810 * In case of a movs spanning multiple pages, we break the accesses
811 * up into multiple pages (the device model works with non-continguous
812 * physical guest pages). To copy just one page, we adjust %ecx and
813 * do not advance %eip so that the next "rep movs" copies the next page.
814 * Unaligned accesses, for example movsl starting at PGSZ-2, are
815 * turned into a single copy where we handle the overlapping memory
816 * copy ourself. After this copy succeeds, "rep movs" is executed
817 * again.
818 */
819 if ((addr & PAGE_MASK) != ((addr + size - 1) & PAGE_MASK)) {
820 unsigned long value = 0;
822 mmio_opp->flags |= OVERLAP;
824 regs->eip -= inst_len; /* do not advance %eip */
826 if (dir == IOREQ_WRITE)
827 vmx_copy(&value, addr, size, VMX_COPY_IN);
828 send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, size, value, dir, 0);
829 } else {
830 if ((addr & PAGE_MASK) != ((addr + count * size - 1) & PAGE_MASK)) {
831 regs->eip -= inst_len; /* do not advance %eip */
833 if (sign > 0)
834 count = (PAGE_SIZE - (addr & ~PAGE_MASK)) / size;
835 else
836 count = (addr & ~PAGE_MASK) / size;
837 }
839 send_mmio_req(IOREQ_TYPE_COPY, gpa, count, size, addr, dir, 1);
840 }
841 break;
842 }
844 case INSTR_MOVZX:
845 case INSTR_MOVSX:
846 mmio_operands(IOREQ_TYPE_COPY, gpa, &mmio_inst, mmio_opp, regs);
847 break;
849 case INSTR_STOS:
850 /*
851 * Since the destination is always in (contiguous) mmio space we don't
852 * need to break it up into pages.
853 */
854 mmio_opp->flags = mmio_inst.flags;
855 mmio_opp->instr = mmio_inst.instr;
856 send_mmio_req(IOREQ_TYPE_COPY, gpa,
857 GET_REPEAT_COUNT(), mmio_inst.op_size, regs->eax, IOREQ_WRITE, 0);
858 break;
860 case INSTR_OR:
861 mmio_operands(IOREQ_TYPE_OR, gpa, &mmio_inst, mmio_opp, regs);
862 break;
864 case INSTR_AND:
865 mmio_operands(IOREQ_TYPE_AND, gpa, &mmio_inst, mmio_opp, regs);
866 break;
868 case INSTR_XOR:
869 mmio_operands(IOREQ_TYPE_XOR, gpa, &mmio_inst, mmio_opp, regs);
870 break;
872 case INSTR_CMP: /* Pass through */
873 case INSTR_TEST:
874 mmio_opp->flags = mmio_inst.flags;
875 mmio_opp->instr = mmio_inst.instr;
876 mmio_opp->operand[0] = mmio_inst.operand[0]; /* source */
877 mmio_opp->operand[1] = mmio_inst.operand[1]; /* destination */
878 mmio_opp->immediate = mmio_inst.immediate;
880 /* send the request and wait for the value */
881 send_mmio_req(IOREQ_TYPE_COPY, gpa, 1,
882 mmio_inst.op_size, 0, IOREQ_READ, 0);
883 break;
885 case INSTR_BT:
886 {
887 unsigned long value = 0;
888 int index, size;
890 mmio_opp->instr = mmio_inst.instr;
891 mmio_opp->operand[0] = mmio_inst.operand[0]; /* bit offset */
892 mmio_opp->operand[1] = mmio_inst.operand[1]; /* bit base */
894 index = operand_index(mmio_inst.operand[0]);
895 size = operand_size(mmio_inst.operand[0]);
896 value = get_reg_value(size, index, 0, regs);
898 send_mmio_req(IOREQ_TYPE_COPY, gpa + (value >> 5), 1,
899 mmio_inst.op_size, 0, IOREQ_READ, 0);
900 break;
901 }
903 default:
904 printf("Unhandled MMIO instruction\n");
905 domain_crash_synchronous();
906 }
907 }
909 #endif /* CONFIG_VMX */
911 /*
912 * Local variables:
913 * mode: C
914 * c-set-style: "BSD"
915 * c-basic-offset: 4
916 * tab-width: 4
917 * indent-tabs-mode: nil
918 * End:
919 */