]> Git Repo - qemu.git/blob - hw/i386/kvmvapic.c
Merge branch 'tcg-s390' of git://github.com/rth7680/qemu
[qemu.git] / hw / i386 / kvmvapic.c
1 /*
2  * TPR optimization for 32-bit Windows guests (XP and Server 2003)
3  *
4  * Copyright (C) 2007-2008 Qumranet Technologies
5  * Copyright (C) 2012      Jan Kiszka, Siemens AG
6  *
7  * This work is licensed under the terms of the GNU GPL version 2, or
8  * (at your option) any later version. See the COPYING file in the
9  * top-level directory.
10  */
11 #include "sysemu/sysemu.h"
12 #include "sysemu/cpus.h"
13 #include "sysemu/kvm.h"
14 #include "hw/i386/apic_internal.h"
15
16 #define VAPIC_IO_PORT           0x7e
17
18 #define VAPIC_CPU_SHIFT         7
19
20 #define ROM_BLOCK_SIZE          512
21 #define ROM_BLOCK_MASK          (~(ROM_BLOCK_SIZE - 1))
22
23 typedef enum VAPICMode {
24     VAPIC_INACTIVE = 0,
25     VAPIC_ACTIVE   = 1,
26     VAPIC_STANDBY  = 2,
27 } VAPICMode;
28
29 typedef struct VAPICHandlers {
30     uint32_t set_tpr;
31     uint32_t set_tpr_eax;
32     uint32_t get_tpr[8];
33     uint32_t get_tpr_stack;
34 } QEMU_PACKED VAPICHandlers;
35
36 typedef struct GuestROMState {
37     char signature[8];
38     uint32_t vaddr;
39     uint32_t fixup_start;
40     uint32_t fixup_end;
41     uint32_t vapic_vaddr;
42     uint32_t vapic_size;
43     uint32_t vcpu_shift;
44     uint32_t real_tpr_addr;
45     VAPICHandlers up;
46     VAPICHandlers mp;
47 } QEMU_PACKED GuestROMState;
48
49 typedef struct VAPICROMState {
50     SysBusDevice busdev;
51     MemoryRegion io;
52     MemoryRegion rom;
53     uint32_t state;
54     uint32_t rom_state_paddr;
55     uint32_t rom_state_vaddr;
56     uint32_t vapic_paddr;
57     uint32_t real_tpr_addr;
58     GuestROMState rom_state;
59     size_t rom_size;
60     bool rom_mapped_writable;
61 } VAPICROMState;
62
63 #define TPR_INSTR_ABS_MODRM             0x1
64 #define TPR_INSTR_MATCH_MODRM_REG       0x2
65
66 typedef struct TPRInstruction {
67     uint8_t opcode;
68     uint8_t modrm_reg;
69     unsigned int flags;
70     TPRAccess access;
71     size_t length;
72     off_t addr_offset;
73 } TPRInstruction;
74
75 /* must be sorted by length, shortest first */
76 static const TPRInstruction tpr_instr[] = {
77     { /* mov abs to eax */
78         .opcode = 0xa1,
79         .access = TPR_ACCESS_READ,
80         .length = 5,
81         .addr_offset = 1,
82     },
83     { /* mov eax to abs */
84         .opcode = 0xa3,
85         .access = TPR_ACCESS_WRITE,
86         .length = 5,
87         .addr_offset = 1,
88     },
89     { /* mov r32 to r/m32 */
90         .opcode = 0x89,
91         .flags = TPR_INSTR_ABS_MODRM,
92         .access = TPR_ACCESS_WRITE,
93         .length = 6,
94         .addr_offset = 2,
95     },
96     { /* mov r/m32 to r32 */
97         .opcode = 0x8b,
98         .flags = TPR_INSTR_ABS_MODRM,
99         .access = TPR_ACCESS_READ,
100         .length = 6,
101         .addr_offset = 2,
102     },
103     { /* push r/m32 */
104         .opcode = 0xff,
105         .modrm_reg = 6,
106         .flags = TPR_INSTR_ABS_MODRM | TPR_INSTR_MATCH_MODRM_REG,
107         .access = TPR_ACCESS_READ,
108         .length = 6,
109         .addr_offset = 2,
110     },
111     { /* mov imm32, r/m32 (c7/0) */
112         .opcode = 0xc7,
113         .modrm_reg = 0,
114         .flags = TPR_INSTR_ABS_MODRM | TPR_INSTR_MATCH_MODRM_REG,
115         .access = TPR_ACCESS_WRITE,
116         .length = 10,
117         .addr_offset = 2,
118     },
119 };
120
121 static void read_guest_rom_state(VAPICROMState *s)
122 {
123     cpu_physical_memory_rw(s->rom_state_paddr, (void *)&s->rom_state,
124                            sizeof(GuestROMState), 0);
125 }
126
127 static void write_guest_rom_state(VAPICROMState *s)
128 {
129     cpu_physical_memory_rw(s->rom_state_paddr, (void *)&s->rom_state,
130                            sizeof(GuestROMState), 1);
131 }
132
133 static void update_guest_rom_state(VAPICROMState *s)
134 {
135     read_guest_rom_state(s);
136
137     s->rom_state.real_tpr_addr = cpu_to_le32(s->real_tpr_addr);
138     s->rom_state.vcpu_shift = cpu_to_le32(VAPIC_CPU_SHIFT);
139
140     write_guest_rom_state(s);
141 }
142
143 static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
144 {
145     hwaddr paddr;
146     target_ulong addr;
147
148     if (s->state == VAPIC_ACTIVE) {
149         return 0;
150     }
151     /*
152      * If there is no prior TPR access instruction we could analyze (which is
153      * the case after resume from hibernation), we need to scan the possible
154      * virtual address space for the APIC mapping.
155      */
156     for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
157         paddr = cpu_get_phys_page_debug(env, addr);
158         if (paddr != APIC_DEFAULT_ADDRESS) {
159             continue;
160         }
161         s->real_tpr_addr = addr + 0x80;
162         update_guest_rom_state(s);
163         return 0;
164     }
165     return -1;
166 }
167
168 static uint8_t modrm_reg(uint8_t modrm)
169 {
170     return (modrm >> 3) & 7;
171 }
172
173 static bool is_abs_modrm(uint8_t modrm)
174 {
175     return (modrm & 0xc7) == 0x05;
176 }
177
178 static bool opcode_matches(uint8_t *opcode, const TPRInstruction *instr)
179 {
180     return opcode[0] == instr->opcode &&
181         (!(instr->flags & TPR_INSTR_ABS_MODRM) || is_abs_modrm(opcode[1])) &&
182         (!(instr->flags & TPR_INSTR_MATCH_MODRM_REG) ||
183          modrm_reg(opcode[1]) == instr->modrm_reg);
184 }
185
186 static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
187                                     target_ulong *pip, TPRAccess access)
188 {
189     const TPRInstruction *instr;
190     target_ulong ip = *pip;
191     uint8_t opcode[2];
192     uint32_t real_tpr_addr;
193     int i;
194
195     if ((ip & 0xf0000000ULL) != 0x80000000ULL &&
196         (ip & 0xf0000000ULL) != 0xe0000000ULL) {
197         return -1;
198     }
199
200     /*
201      * Early Windows 2003 SMP initialization contains a
202      *
203      *   mov imm32, r/m32
204      *
205      * instruction that is patched by TPR optimization. The problem is that
206      * RSP, used by the patched instruction, is zero, so the guest gets a
207      * double fault and dies.
208      */
209     if (env->regs[R_ESP] == 0) {
210         return -1;
211     }
212
213     if (kvm_enabled() && !kvm_irqchip_in_kernel()) {
214         /*
215          * KVM without kernel-based TPR access reporting will pass an IP that
216          * points after the accessing instruction. So we need to look backward
217          * to find the reason.
218          */
219         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
220             instr = &tpr_instr[i];
221             if (instr->access != access) {
222                 continue;
223             }
224             if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
225                                     sizeof(opcode), 0) < 0) {
226                 return -1;
227             }
228             if (opcode_matches(opcode, instr)) {
229                 ip -= instr->length;
230                 goto instruction_ok;
231             }
232         }
233         return -1;
234     } else {
235         if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
236             return -1;
237         }
238         for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
239             instr = &tpr_instr[i];
240             if (opcode_matches(opcode, instr)) {
241                 goto instruction_ok;
242             }
243         }
244         return -1;
245     }
246
247 instruction_ok:
248     /*
249      * Grab the virtual TPR address from the instruction
250      * and update the cached values.
251      */
252     if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
253                             (void *)&real_tpr_addr,
254                             sizeof(real_tpr_addr), 0) < 0) {
255         return -1;
256     }
257     real_tpr_addr = le32_to_cpu(real_tpr_addr);
258     if ((real_tpr_addr & 0xfff) != 0x80) {
259         return -1;
260     }
261     s->real_tpr_addr = real_tpr_addr;
262     update_guest_rom_state(s);
263
264     *pip = ip;
265     return 0;
266 }
267
268 static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
269 {
270     hwaddr paddr;
271     uint32_t rom_state_vaddr;
272     uint32_t pos, patch, offset;
273
274     /* nothing to do if already activated */
275     if (s->state == VAPIC_ACTIVE) {
276         return 0;
277     }
278
279     /* bail out if ROM init code was not executed (missing ROM?) */
280     if (s->state == VAPIC_INACTIVE) {
281         return -1;
282     }
283
284     /* find out virtual address of the ROM */
285     rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
286     paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
287     if (paddr == -1) {
288         return -1;
289     }
290     paddr += rom_state_vaddr & ~TARGET_PAGE_MASK;
291     if (paddr != s->rom_state_paddr) {
292         return -1;
293     }
294     read_guest_rom_state(s);
295     if (memcmp(s->rom_state.signature, "kvm aPiC", 8) != 0) {
296         return -1;
297     }
298     s->rom_state_vaddr = rom_state_vaddr;
299
300     /* fixup addresses in ROM if needed */
301     if (rom_state_vaddr == le32_to_cpu(s->rom_state.vaddr)) {
302         return 0;
303     }
304     for (pos = le32_to_cpu(s->rom_state.fixup_start);
305          pos < le32_to_cpu(s->rom_state.fixup_end);
306          pos += 4) {
307         cpu_physical_memory_rw(paddr + pos - s->rom_state.vaddr,
308                                (void *)&offset, sizeof(offset), 0);
309         offset = le32_to_cpu(offset);
310         cpu_physical_memory_rw(paddr + offset, (void *)&patch,
311                                sizeof(patch), 0);
312         patch = le32_to_cpu(patch);
313         patch += rom_state_vaddr - le32_to_cpu(s->rom_state.vaddr);
314         patch = cpu_to_le32(patch);
315         cpu_physical_memory_rw(paddr + offset, (void *)&patch,
316                                sizeof(patch), 1);
317     }
318     read_guest_rom_state(s);
319     s->vapic_paddr = paddr + le32_to_cpu(s->rom_state.vapic_vaddr) -
320         le32_to_cpu(s->rom_state.vaddr);
321
322     return 0;
323 }
324
325 /*
326  * Tries to read the unique processor number from the Kernel Processor Control
327  * Region (KPCR) of 32-bit Windows XP and Server 2003. Returns -1 if the KPCR
328  * cannot be accessed or is considered invalid. This also ensures that we are
329  * not patching the wrong guest.
330  */
331 static int get_kpcr_number(CPUX86State *env)
332 {
333     struct kpcr {
334         uint8_t  fill1[0x1c];
335         uint32_t self;
336         uint8_t  fill2[0x31];
337         uint8_t  number;
338     } QEMU_PACKED kpcr;
339
340     if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
341                             (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
342         kpcr.self != env->segs[R_FS].base) {
343         return -1;
344     }
345     return kpcr.number;
346 }
347
348 static int vapic_enable(VAPICROMState *s, CPUX86State *env)
349 {
350     int cpu_number = get_kpcr_number(env);
351     hwaddr vapic_paddr;
352     static const uint8_t enabled = 1;
353
354     if (cpu_number < 0) {
355         return -1;
356     }
357     vapic_paddr = s->vapic_paddr +
358         (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
359     cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
360                            (void *)&enabled, sizeof(enabled), 1);
361     apic_enable_vapic(env->apic_state, vapic_paddr);
362
363     s->state = VAPIC_ACTIVE;
364
365     return 0;
366 }
367
368 static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
369 {
370     cpu_memory_rw_debug(env, addr, &byte, 1, 1);
371 }
372
373 static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
374                        uint32_t target)
375 {
376     uint32_t offset;
377
378     offset = cpu_to_le32(target - ip - 5);
379     patch_byte(env, ip, 0xe8); /* call near */
380     cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
381 }
382
383 static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
384 {
385     CPUState *cs = CPU(cpu);
386     CPUX86State *env = &cpu->env;
387     VAPICHandlers *handlers;
388     uint8_t opcode[2];
389     uint32_t imm32;
390     target_ulong current_pc = 0;
391     target_ulong current_cs_base = 0;
392     int current_flags = 0;
393
394     if (smp_cpus == 1) {
395         handlers = &s->rom_state.up;
396     } else {
397         handlers = &s->rom_state.mp;
398     }
399
400     if (!kvm_enabled()) {
401         cpu_restore_state(env, env->mem_io_pc);
402         cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base,
403                              &current_flags);
404     }
405
406     pause_all_vcpus();
407
408     cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
409
410     switch (opcode[0]) {
411     case 0x89: /* mov r32 to r/m32 */
412         patch_byte(env, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
413         patch_call(s, env, ip + 1, handlers->set_tpr);
414         break;
415     case 0x8b: /* mov r/m32 to r32 */
416         patch_byte(env, ip, 0x90);
417         patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
418         break;
419     case 0xa1: /* mov abs to eax */
420         patch_call(s, env, ip, handlers->get_tpr[0]);
421         break;
422     case 0xa3: /* mov eax to abs */
423         patch_call(s, env, ip, handlers->set_tpr_eax);
424         break;
425     case 0xc7: /* mov imm32, r/m32 (c7/0) */
426         patch_byte(env, ip, 0x68);  /* push imm32 */
427         cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
428         cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
429         patch_call(s, env, ip + 5, handlers->set_tpr);
430         break;
431     case 0xff: /* push r/m32 */
432         patch_byte(env, ip, 0x50); /* push eax */
433         patch_call(s, env, ip + 1, handlers->get_tpr_stack);
434         break;
435     default:
436         abort();
437     }
438
439     resume_all_vcpus();
440
441     if (!kvm_enabled()) {
442         cs->current_tb = NULL;
443         tb_gen_code(env, current_pc, current_cs_base, current_flags, 1);
444         cpu_resume_from_signal(env, NULL);
445     }
446 }
447
448 void vapic_report_tpr_access(DeviceState *dev, CPUState *cs, target_ulong ip,
449                              TPRAccess access)
450 {
451     VAPICROMState *s = DO_UPCAST(VAPICROMState, busdev.qdev, dev);
452     X86CPU *cpu = X86_CPU(cs);
453     CPUX86State *env = &cpu->env;
454
455     cpu_synchronize_state(env);
456
457     if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
458         if (s->state == VAPIC_ACTIVE) {
459             vapic_enable(s, env);
460         }
461         return;
462     }
463     if (update_rom_mapping(s, env, ip) < 0) {
464         return;
465     }
466     if (vapic_enable(s, env) < 0) {
467         return;
468     }
469     patch_instruction(s, cpu, ip);
470 }
471
472 typedef struct VAPICEnableTPRReporting {
473     DeviceState *apic;
474     bool enable;
475 } VAPICEnableTPRReporting;
476
477 static void vapic_do_enable_tpr_reporting(void *data)
478 {
479     VAPICEnableTPRReporting *info = data;
480
481     apic_enable_tpr_access_reporting(info->apic, info->enable);
482 }
483
484 static void vapic_enable_tpr_reporting(bool enable)
485 {
486     VAPICEnableTPRReporting info = {
487         .enable = enable,
488     };
489     X86CPU *cpu;
490     CPUX86State *env;
491
492     for (env = first_cpu; env != NULL; env = env->next_cpu) {
493         cpu = x86_env_get_cpu(env);
494         info.apic = env->apic_state;
495         run_on_cpu(CPU(cpu), vapic_do_enable_tpr_reporting, &info);
496     }
497 }
498
499 static void vapic_reset(DeviceState *dev)
500 {
501     VAPICROMState *s = DO_UPCAST(VAPICROMState, busdev.qdev, dev);
502
503     if (s->state == VAPIC_ACTIVE) {
504         s->state = VAPIC_STANDBY;
505     }
506     vapic_enable_tpr_reporting(false);
507 }
508
509 /*
510  * Set the IRQ polling hypercalls to the supported variant:
511  *  - vmcall if using KVM in-kernel irqchip
512  *  - 32-bit VAPIC port write otherwise
513  */
514 static int patch_hypercalls(VAPICROMState *s)
515 {
516     hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK;
517     static const uint8_t vmcall_pattern[] = { /* vmcall */
518         0xb8, 0x1, 0, 0, 0, 0xf, 0x1, 0xc1
519     };
520     static const uint8_t outl_pattern[] = { /* nop; outl %eax,0x7e */
521         0xb8, 0x1, 0, 0, 0, 0x90, 0xe7, 0x7e
522     };
523     uint8_t alternates[2];
524     const uint8_t *pattern;
525     const uint8_t *patch;
526     int patches = 0;
527     off_t pos;
528     uint8_t *rom;
529
530     rom = g_malloc(s->rom_size);
531     cpu_physical_memory_rw(rom_paddr, rom, s->rom_size, 0);
532
533     for (pos = 0; pos < s->rom_size - sizeof(vmcall_pattern); pos++) {
534         if (kvm_irqchip_in_kernel()) {
535             pattern = outl_pattern;
536             alternates[0] = outl_pattern[7];
537             alternates[1] = outl_pattern[7];
538             patch = &vmcall_pattern[5];
539         } else {
540             pattern = vmcall_pattern;
541             alternates[0] = vmcall_pattern[7];
542             alternates[1] = 0xd9; /* AMD's VMMCALL */
543             patch = &outl_pattern[5];
544         }
545         if (memcmp(rom + pos, pattern, 7) == 0 &&
546             (rom[pos + 7] == alternates[0] || rom[pos + 7] == alternates[1])) {
547             cpu_physical_memory_rw(rom_paddr + pos + 5, (uint8_t *)patch,
548                                    3, 1);
549             /*
550              * Don't flush the tb here. Under ordinary conditions, the patched
551              * calls are miles away from the current IP. Under malicious
552              * conditions, the guest could trick us to crash.
553              */
554         }
555     }
556
557     g_free(rom);
558
559     if (patches != 0 && patches != 2) {
560         return -1;
561     }
562
563     return 0;
564 }
565
566 /*
567  * For TCG mode or the time KVM honors read-only memory regions, we need to
568  * enable write access to the option ROM so that variables can be updated by
569  * the guest.
570  */
571 static void vapic_map_rom_writable(VAPICROMState *s)
572 {
573     hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK;
574     MemoryRegionSection section;
575     MemoryRegion *as;
576     size_t rom_size;
577     uint8_t *ram;
578
579     as = sysbus_address_space(&s->busdev);
580
581     if (s->rom_mapped_writable) {
582         memory_region_del_subregion(as, &s->rom);
583         memory_region_destroy(&s->rom);
584     }
585
586     /* grab RAM memory region (region @rom_paddr may still be pc.rom) */
587     section = memory_region_find(as, 0, 1);
588
589     /* read ROM size from RAM region */
590     ram = memory_region_get_ram_ptr(section.mr);
591     rom_size = ram[rom_paddr + 2] * ROM_BLOCK_SIZE;
592     s->rom_size = rom_size;
593
594     /* We need to round to avoid creating subpages
595      * from which we cannot run code. */
596     rom_size += rom_paddr & ~TARGET_PAGE_MASK;
597     rom_paddr &= TARGET_PAGE_MASK;
598     rom_size = TARGET_PAGE_ALIGN(rom_size);
599
600     memory_region_init_alias(&s->rom, "kvmvapic-rom", section.mr, rom_paddr,
601                              rom_size);
602     memory_region_add_subregion_overlap(as, rom_paddr, &s->rom, 1000);
603     s->rom_mapped_writable = true;
604 }
605
606 static int vapic_prepare(VAPICROMState *s)
607 {
608     vapic_map_rom_writable(s);
609
610     if (patch_hypercalls(s) < 0) {
611         return -1;
612     }
613
614     vapic_enable_tpr_reporting(true);
615
616     return 0;
617 }
618
619 static void vapic_write(void *opaque, hwaddr addr, uint64_t data,
620                         unsigned int size)
621 {
622     CPUX86State *env = cpu_single_env;
623     hwaddr rom_paddr;
624     VAPICROMState *s = opaque;
625
626     cpu_synchronize_state(env);
627
628     /*
629      * The VAPIC supports two PIO-based hypercalls, both via port 0x7E.
630      *  o 16-bit write access:
631      *    Reports the option ROM initialization to the hypervisor. Written
632      *    value is the offset of the state structure in the ROM.
633      *  o 8-bit write access:
634      *    Reactivates the VAPIC after a guest hibernation, i.e. after the
635      *    option ROM content has been re-initialized by a guest power cycle.
636      *  o 32-bit write access:
637      *    Poll for pending IRQs, considering the current VAPIC state.
638      */
639     switch (size) {
640     case 2:
641         if (s->state == VAPIC_INACTIVE) {
642             rom_paddr = (env->segs[R_CS].base + env->eip) & ROM_BLOCK_MASK;
643             s->rom_state_paddr = rom_paddr + data;
644
645             s->state = VAPIC_STANDBY;
646         }
647         if (vapic_prepare(s) < 0) {
648             s->state = VAPIC_INACTIVE;
649             break;
650         }
651         break;
652     case 1:
653         if (kvm_enabled()) {
654             /*
655              * Disable triggering instruction in ROM by writing a NOP.
656              *
657              * We cannot do this in TCG mode as the reported IP is not
658              * accurate.
659              */
660             pause_all_vcpus();
661             patch_byte(env, env->eip - 2, 0x66);
662             patch_byte(env, env->eip - 1, 0x90);
663             resume_all_vcpus();
664         }
665
666         if (s->state == VAPIC_ACTIVE) {
667             break;
668         }
669         if (update_rom_mapping(s, env, env->eip) < 0) {
670             break;
671         }
672         if (find_real_tpr_addr(s, env) < 0) {
673             break;
674         }
675         vapic_enable(s, env);
676         break;
677     default:
678     case 4:
679         if (!kvm_irqchip_in_kernel()) {
680             apic_poll_irq(env->apic_state);
681         }
682         break;
683     }
684 }
685
686 static const MemoryRegionOps vapic_ops = {
687     .write = vapic_write,
688     .endianness = DEVICE_NATIVE_ENDIAN,
689 };
690
691 static int vapic_init(SysBusDevice *dev)
692 {
693     VAPICROMState *s = FROM_SYSBUS(VAPICROMState, dev);
694
695     memory_region_init_io(&s->io, &vapic_ops, s, "kvmvapic", 2);
696     sysbus_add_io(dev, VAPIC_IO_PORT, &s->io);
697     sysbus_init_ioports(dev, VAPIC_IO_PORT, 2);
698
699     option_rom[nb_option_roms].name = "kvmvapic.bin";
700     option_rom[nb_option_roms].bootindex = -1;
701     nb_option_roms++;
702
703     return 0;
704 }
705
706 static void do_vapic_enable(void *data)
707 {
708     VAPICROMState *s = data;
709
710     vapic_enable(s, first_cpu);
711 }
712
713 static int vapic_post_load(void *opaque, int version_id)
714 {
715     VAPICROMState *s = opaque;
716     uint8_t *zero;
717
718     /*
719      * The old implementation of qemu-kvm did not provide the state
720      * VAPIC_STANDBY. Reconstruct it.
721      */
722     if (s->state == VAPIC_INACTIVE && s->rom_state_paddr != 0) {
723         s->state = VAPIC_STANDBY;
724     }
725
726     if (s->state != VAPIC_INACTIVE) {
727         if (vapic_prepare(s) < 0) {
728             return -1;
729         }
730     }
731     if (s->state == VAPIC_ACTIVE) {
732         if (smp_cpus == 1) {
733             run_on_cpu(ENV_GET_CPU(first_cpu), do_vapic_enable, s);
734         } else {
735             zero = g_malloc0(s->rom_state.vapic_size);
736             cpu_physical_memory_rw(s->vapic_paddr, zero,
737                                    s->rom_state.vapic_size, 1);
738             g_free(zero);
739         }
740     }
741
742     return 0;
743 }
744
745 static const VMStateDescription vmstate_handlers = {
746     .name = "kvmvapic-handlers",
747     .version_id = 1,
748     .minimum_version_id = 1,
749     .minimum_version_id_old = 1,
750     .fields = (VMStateField[]) {
751         VMSTATE_UINT32(set_tpr, VAPICHandlers),
752         VMSTATE_UINT32(set_tpr_eax, VAPICHandlers),
753         VMSTATE_UINT32_ARRAY(get_tpr, VAPICHandlers, 8),
754         VMSTATE_UINT32(get_tpr_stack, VAPICHandlers),
755         VMSTATE_END_OF_LIST()
756     }
757 };
758
759 static const VMStateDescription vmstate_guest_rom = {
760     .name = "kvmvapic-guest-rom",
761     .version_id = 1,
762     .minimum_version_id = 1,
763     .minimum_version_id_old = 1,
764     .fields = (VMStateField[]) {
765         VMSTATE_UNUSED(8),     /* signature */
766         VMSTATE_UINT32(vaddr, GuestROMState),
767         VMSTATE_UINT32(fixup_start, GuestROMState),
768         VMSTATE_UINT32(fixup_end, GuestROMState),
769         VMSTATE_UINT32(vapic_vaddr, GuestROMState),
770         VMSTATE_UINT32(vapic_size, GuestROMState),
771         VMSTATE_UINT32(vcpu_shift, GuestROMState),
772         VMSTATE_UINT32(real_tpr_addr, GuestROMState),
773         VMSTATE_STRUCT(up, GuestROMState, 0, vmstate_handlers, VAPICHandlers),
774         VMSTATE_STRUCT(mp, GuestROMState, 0, vmstate_handlers, VAPICHandlers),
775         VMSTATE_END_OF_LIST()
776     }
777 };
778
779 static const VMStateDescription vmstate_vapic = {
780     .name = "kvm-tpr-opt",      /* compatible with qemu-kvm VAPIC */
781     .version_id = 1,
782     .minimum_version_id = 1,
783     .minimum_version_id_old = 1,
784     .post_load = vapic_post_load,
785     .fields = (VMStateField[]) {
786         VMSTATE_STRUCT(rom_state, VAPICROMState, 0, vmstate_guest_rom,
787                        GuestROMState),
788         VMSTATE_UINT32(state, VAPICROMState),
789         VMSTATE_UINT32(real_tpr_addr, VAPICROMState),
790         VMSTATE_UINT32(rom_state_vaddr, VAPICROMState),
791         VMSTATE_UINT32(vapic_paddr, VAPICROMState),
792         VMSTATE_UINT32(rom_state_paddr, VAPICROMState),
793         VMSTATE_END_OF_LIST()
794     }
795 };
796
797 static void vapic_class_init(ObjectClass *klass, void *data)
798 {
799     SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
800     DeviceClass *dc = DEVICE_CLASS(klass);
801
802     dc->no_user = 1;
803     dc->reset   = vapic_reset;
804     dc->vmsd    = &vmstate_vapic;
805     sc->init    = vapic_init;
806 }
807
808 static const TypeInfo vapic_type = {
809     .name          = "kvmvapic",
810     .parent        = TYPE_SYS_BUS_DEVICE,
811     .instance_size = sizeof(VAPICROMState),
812     .class_init    = vapic_class_init,
813 };
814
815 static void vapic_register(void)
816 {
817     type_register_static(&vapic_type);
818 }
819
820 type_init(vapic_register);
This page took 0.069543 seconds and 4 git commands to generate.