Lines Matching +full:rom +full:- +full:addr

2  * TPR optimization for 32-bit Windows guests (XP and Server 2003)
4 * Copyright (C) 2007-2008 Qumranet Technologies
9 * top-level directory.
19 #include "exec/address-spaces.h"
31 #define ROM_BLOCK_MASK (~(ROM_BLOCK_SIZE - 1))
63 MemoryRegion rom; member
138 cpu_physical_memory_read(s->rom_state_paddr, &s->rom_state, in read_guest_rom_state()
144 cpu_physical_memory_write(s->rom_state_paddr, &s->rom_state, in write_guest_rom_state()
152 s->rom_state.real_tpr_addr = cpu_to_le32(s->real_tpr_addr); in update_guest_rom_state()
153 s->rom_state.vcpu_shift = cpu_to_le32(VAPIC_CPU_SHIFT); in update_guest_rom_state()
162 target_ulong addr; in find_real_tpr_addr() local
164 if (s->state == VAPIC_ACTIVE) { in find_real_tpr_addr()
172 for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) { in find_real_tpr_addr()
173 paddr = cpu_get_phys_page_debug(cs, addr); in find_real_tpr_addr()
177 s->real_tpr_addr = addr + 0x80; in find_real_tpr_addr()
181 return -1; in find_real_tpr_addr()
196 return opcode[0] == instr->opcode && in opcode_matches()
197 (!(instr->flags & TPR_INSTR_ABS_MODRM) || is_abs_modrm(opcode[1])) && in opcode_matches()
198 (!(instr->flags & TPR_INSTR_MATCH_MODRM_REG) || in opcode_matches()
199 modrm_reg(opcode[1]) == instr->modrm_reg); in opcode_matches()
214 return -1; in evaluate_tpr_instruction()
226 if (cpu->env.regs[R_ESP] == 0) { in evaluate_tpr_instruction()
227 return -1; in evaluate_tpr_instruction()
232 * KVM without kernel-based TPR access reporting will pass an IP that in evaluate_tpr_instruction()
238 if (instr->access != access) { in evaluate_tpr_instruction()
241 if (cpu_memory_rw_debug(cs, ip - instr->length, opcode, in evaluate_tpr_instruction()
243 return -1; in evaluate_tpr_instruction()
246 ip -= instr->length; in evaluate_tpr_instruction()
250 return -1; in evaluate_tpr_instruction()
253 return -1; in evaluate_tpr_instruction()
261 return -1; in evaluate_tpr_instruction()
269 if (cpu_memory_rw_debug(cs, ip + instr->addr_offset, in evaluate_tpr_instruction()
272 return -1; in evaluate_tpr_instruction()
276 return -1; in evaluate_tpr_instruction()
278 s->real_tpr_addr = real_tpr_addr; in evaluate_tpr_instruction()
293 if (s->state == VAPIC_ACTIVE) { in update_rom_mapping()
297 /* bail out if ROM init code was not executed (missing ROM?) */ in update_rom_mapping()
298 if (s->state == VAPIC_INACTIVE) { in update_rom_mapping()
299 return -1; in update_rom_mapping()
302 /* find out virtual address of the ROM */ in update_rom_mapping()
303 rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000); in update_rom_mapping()
305 if (paddr == -1) { in update_rom_mapping()
306 return -1; in update_rom_mapping()
309 if (paddr != s->rom_state_paddr) { in update_rom_mapping()
310 return -1; in update_rom_mapping()
313 if (memcmp(s->rom_state.signature, "kvm aPiC", 8) != 0) { in update_rom_mapping()
314 return -1; in update_rom_mapping()
316 s->rom_state_vaddr = rom_state_vaddr; in update_rom_mapping()
318 /* fixup addresses in ROM if needed */ in update_rom_mapping()
319 if (rom_state_vaddr == le32_to_cpu(s->rom_state.vaddr)) { in update_rom_mapping()
322 for (pos = le32_to_cpu(s->rom_state.fixup_start); in update_rom_mapping()
323 pos < le32_to_cpu(s->rom_state.fixup_end); in update_rom_mapping()
325 cpu_physical_memory_read(paddr + pos - s->rom_state.vaddr, in update_rom_mapping()
330 patch += rom_state_vaddr - le32_to_cpu(s->rom_state.vaddr); in update_rom_mapping()
335 s->vapic_paddr = paddr + le32_to_cpu(s->rom_state.vapic_vaddr) - in update_rom_mapping()
336 le32_to_cpu(s->rom_state.vaddr); in update_rom_mapping()
343 * Region (KPCR) of 32-bit Windows XP and Server 2003. Returns -1 if the KPCR
349 CPUX86State *env = &cpu->env; in get_kpcr_number()
357 if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base, in get_kpcr_number()
359 kpcr.self != env->segs[R_FS].base) { in get_kpcr_number()
360 return -1; in get_kpcr_number()
372 return -1; in vapic_enable()
374 vapic_paddr = s->vapic_paddr + in vapic_enable()
378 apic_enable_vapic(cpu->apic_state, vapic_paddr); in vapic_enable()
380 s->state = VAPIC_ACTIVE; in vapic_enable()
385 static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte) in patch_byte() argument
387 cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1); in patch_byte()
394 offset = cpu_to_le32(target - ip - 5); in patch_call()
408 VAPICHandlers *handlers = info->handler; in do_patch_instruction()
409 target_ulong ip = info->ip; in do_patch_instruction()
418 patch_call(x86_cpu, ip + 1, handlers->set_tpr); in do_patch_instruction()
422 patch_call(x86_cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]); in do_patch_instruction()
425 patch_call(x86_cpu, ip, handlers->get_tpr[0]); in do_patch_instruction()
428 patch_call(x86_cpu, ip, handlers->set_tpr_eax); in do_patch_instruction()
434 patch_call(x86_cpu, ip + 5, handlers->set_tpr); in do_patch_instruction()
438 patch_call(x86_cpu, ip + 1, handlers->get_tpr_stack); in do_patch_instruction()
454 if (ms->smp.cpus == 1) { in patch_instruction()
455 handlers = &s->rom_state.up; in patch_instruction()
457 handlers = &s->rom_state.mp; in patch_instruction()
461 info->handler = handlers; in patch_instruction()
462 info->ip = ip; in patch_instruction()
472 CPUX86State *env = &cpu->env; in vapic_report_tpr_access()
477 if (s->state == VAPIC_ACTIVE) { in vapic_report_tpr_access()
499 apic_enable_tpr_access_reporting(info->apic, info->enable); in vapic_do_enable_tpr_reporting()
512 info.apic = cpu->apic_state; in vapic_enable_tpr_reporting()
521 s->state = VAPIC_INACTIVE; in vapic_reset()
522 s->rom_state_paddr = 0; in vapic_reset()
528 * - vmcall if using KVM in-kernel irqchip
529 * - 32-bit VAPIC port write otherwise
533 hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK; in patch_hypercalls()
544 uint8_t *rom; in patch_hypercalls() local
546 rom = g_malloc(s->rom_size); in patch_hypercalls()
547 cpu_physical_memory_read(rom_paddr, rom, s->rom_size); in patch_hypercalls()
549 for (pos = 0; pos < s->rom_size - sizeof(vmcall_pattern); pos++) { in patch_hypercalls()
561 if (memcmp(rom + pos, pattern, 7) == 0 && in patch_hypercalls()
562 (rom[pos + 7] == alternates[0] || rom[pos + 7] == alternates[1])) { in patch_hypercalls()
572 g_free(rom); in patch_hypercalls()
577 * For TCG mode or the time KVM honors read-only memory regions, we need to
578 * enable write access to the option ROM so that variables can be updated by
583 hwaddr rom_paddr = s->rom_state_paddr & ROM_BLOCK_MASK; in vapic_map_rom_writable()
589 if (s->rom_mapped_writable) { in vapic_map_rom_writable()
590 memory_region_del_subregion(mr, &s->rom); in vapic_map_rom_writable()
591 object_unparent(OBJECT(&s->rom)); in vapic_map_rom_writable()
594 /* grab RAM memory region (region @rom_paddr may still be pc.rom) */ in vapic_map_rom_writable()
597 /* read ROM size from RAM region */ in vapic_map_rom_writable()
599 return -1; in vapic_map_rom_writable()
604 return -1; in vapic_map_rom_writable()
606 s->rom_size = rom_size; in vapic_map_rom_writable()
614 memory_region_init_alias(&s->rom, OBJECT(s), "kvmvapic-rom", section.mr, in vapic_map_rom_writable()
616 memory_region_add_subregion_overlap(mr, rom_paddr, &s->rom, 1000); in vapic_map_rom_writable()
617 s->rom_mapped_writable = true; in vapic_map_rom_writable()
626 return -1; in vapic_prepare()
630 return -1; in vapic_prepare()
638 static void vapic_write(void *opaque, hwaddr addr, uint64_t data, in vapic_write() argument
652 env = &cpu->env; in vapic_write()
655 * The VAPIC supports two PIO-based hypercalls, both via port 0x7E. in vapic_write()
656 * o 16-bit write access: in vapic_write()
657 * Reports the option ROM initialization to the hypervisor. Written in vapic_write()
658 * value is the offset of the state structure in the ROM. in vapic_write()
659 * o 8-bit write access: in vapic_write()
661 * option ROM content has been re-initialized by a guest power cycle. in vapic_write()
662 * o 32-bit write access: in vapic_write()
667 if (s->state == VAPIC_INACTIVE) { in vapic_write()
668 rom_paddr = (env->segs[R_CS].base + env->eip) & ROM_BLOCK_MASK; in vapic_write()
669 s->rom_state_paddr = rom_paddr + data; in vapic_write()
671 s->state = VAPIC_STANDBY; in vapic_write()
674 s->state = VAPIC_INACTIVE; in vapic_write()
675 s->rom_state_paddr = 0; in vapic_write()
682 * Disable triggering instruction in ROM by writing a NOP. in vapic_write()
688 patch_byte(cpu, env->eip - 2, 0x66); in vapic_write()
689 patch_byte(cpu, env->eip - 1, 0x90); in vapic_write()
693 if (s->state == VAPIC_ACTIVE) { in vapic_write()
696 if (update_rom_mapping(s, env, env->eip) < 0) { in vapic_write()
707 apic_poll_irq(cpu->apic_state); in vapic_write()
713 static uint64_t vapic_read(void *opaque, hwaddr addr, unsigned size) in vapic_read() argument
729 memory_region_init_io(&s->io, OBJECT(s), &vapic_ops, s, "kvmvapic", 2); in vapic_realize()
730 memory_region_add_subregion(get_system_io(), VAPIC_IO_PORT, &s->io); in vapic_realize()
734 option_rom[nb_option_roms].bootindex = -1; in vapic_realize()
744 cpu_physical_memory_write(s->vapic_paddr + offsetof(VAPICState, enabled), in do_vapic_enable()
746 apic_enable_vapic(cpu->apic_state, s->vapic_paddr); in do_vapic_enable()
747 s->state = VAPIC_ACTIVE; in do_vapic_enable()
760 if (s->state == VAPIC_ACTIVE) { in vapic_vm_state_change()
761 if (ms->smp.cpus == 1) { in vapic_vm_state_change()
764 zero = g_malloc0(s->rom_state.vapic_size); in vapic_vm_state_change()
765 cpu_physical_memory_write(s->vapic_paddr, zero, in vapic_vm_state_change()
766 s->rom_state.vapic_size); in vapic_vm_state_change()
771 qemu_del_vm_change_state_handler(s->vmsentry); in vapic_vm_state_change()
772 s->vmsentry = NULL; in vapic_vm_state_change()
780 * The old implementation of qemu-kvm did not provide the state in vapic_post_load()
783 if (s->state == VAPIC_INACTIVE && s->rom_state_paddr != 0) { in vapic_post_load()
784 s->state = VAPIC_STANDBY; in vapic_post_load()
787 if (s->state != VAPIC_INACTIVE) { in vapic_post_load()
789 return -1; in vapic_post_load()
793 if (!s->vmsentry) { in vapic_post_load()
794 s->vmsentry = in vapic_post_load()
801 .name = "kvmvapic-handlers",
814 .name = "kvmvapic-guest-rom",
833 .name = "kvm-tpr-opt", /* compatible with qemu-kvm VAPIC */
854 dc->vmsd = &vmstate_vapic; in vapic_class_init()
855 dc->realize = vapic_realize; in vapic_class_init()