]> git.proxmox.com Git - qemu.git/commitdiff
Merge remote-tracking branch 'afaerber/tags/qom-cpu-for-anthony' into staging
authorAnthony Liguori <aliguori@us.ibm.com>
Tue, 23 Jul 2013 15:57:04 +0000 (10:57 -0500)
committerAnthony Liguori <aliguori@us.ibm.com>
Tue, 23 Jul 2013 15:57:04 +0000 (10:57 -0500)
QOM CPUState refactorings

* Fix NULL pointer dereference in gdbstub
* Introduce vaddr type
* Introduce CPUClass::set_pc()
* Introduce CPUClass::synchronize_from_tb()
* Introduce CPUClass::get_phys_page_debug()
* Introduce CPUClass::memory_rw_debug()
* Move singlestep_enabled and gdb_regs fields out of CPU_COMMON
* Adopt CPUState in more APIs
* Propagate CPUState in gdbstub

# gpg: Signature made Mon 22 Jul 2013 07:50:17 PM CDT using RSA key ID 3E7E013F
# gpg: Can't check signature: public key not found

# By Andreas Färber (21) and others
# Via Andreas Färber
* afaerber/tags/qom-cpu-for-anthony: (24 commits)
  linux-user: Use X86CPU property to retrieve CPUID family
  gdbstub: Change gdb_register_coprocessor() argument to CPUState
  cpu: Move gdb_regs field from CPU_COMMON to CPUState
  gdbstub: Change GDBState::{c,g}_cpu and find_cpu() to CPUState
  cpu: Introduce CPUClass::memory_rw_debug() for target_memory_rw_debug()
  exec: Change cpu_memory_rw_debug() argument to CPUState
  cpu: Turn cpu_get_phys_page_debug() into a CPUClass hook
  gdbstub: Change gdb_{read,write}_register() argument to CPUState
  gdbstub: Change gdb_handlesig() argument to CPUState
  gdbstub: Change syscall callback argument to CPUState
  kvm: Change kvm_{insert,remove}_breakpoint() argument to CPUState
  cpu: Change cpu_single_step() argument to CPUState
  gdbstub: Update gdb_handlesig() and gdb_signalled() Coding Style
  cpu: Move singlestep_enabled field from CPU_COMMON to CPUState
  target-alpha: Copy implver to DisasContext
  target-alpha: Copy singlestep_enabled to DisasContext
  cpu: Introduce CPUClass::synchronize_from_tb() for cpu_pc_from_tb()
  target-unicore32: Implement CPUClass::set_pc()
  target-moxie: Implement CPUClass::set_pc()
  target-m68k: Implement CPUClass::set_pc()
  ...

1  2 
hw/i386/kvmvapic.c

diff --combined hw/i386/kvmvapic.c
index 365b2197a1d21bbd3b47661bd7595a4d0dbb047a,035d0fe48914a5d2ee5ec0bcb59f9150742bf2db..a4506bcf42a2f1801d89505ac14c31eb520ac6cc
@@@ -146,6 -146,7 +146,7 @@@ static void update_guest_rom_state(VAPI
  
  static int find_real_tpr_addr(VAPICROMState *s, CPUX86State *env)
  {
+     CPUState *cs = CPU(x86_env_get_cpu(env));
      hwaddr paddr;
      target_ulong addr;
  
       * virtual address space for the APIC mapping.
       */
      for (addr = 0xfffff000; addr >= 0x80000000; addr -= TARGET_PAGE_SIZE) {
-         paddr = cpu_get_phys_page_debug(env, addr);
+         paddr = cpu_get_phys_page_debug(cs, addr);
          if (paddr != APIC_DEFAULT_ADDRESS) {
              continue;
          }
@@@ -187,9 -188,10 +188,10 @@@ static bool opcode_matches(uint8_t *opc
           modrm_reg(opcode[1]) == instr->modrm_reg);
  }
  
- static int evaluate_tpr_instruction(VAPICROMState *s, CPUX86State *env,
+ static int evaluate_tpr_instruction(VAPICROMState *s, X86CPU *cpu,
                                      target_ulong *pip, TPRAccess access)
  {
+     CPUState *cs = CPU(cpu);
      const TPRInstruction *instr;
      target_ulong ip = *pip;
      uint8_t opcode[2];
       * RSP, used by the patched instruction, is zero, so the guest gets a
       * double fault and dies.
       */
-     if (env->regs[R_ESP] == 0) {
+     if (cpu->env.regs[R_ESP] == 0) {
          return -1;
      }
  
              if (instr->access != access) {
                  continue;
              }
-             if (cpu_memory_rw_debug(env, ip - instr->length, opcode,
+             if (cpu_memory_rw_debug(cs, ip - instr->length, opcode,
                                      sizeof(opcode), 0) < 0) {
                  return -1;
              }
          }
          return -1;
      } else {
-         if (cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0) < 0) {
+         if (cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0) < 0) {
              return -1;
          }
          for (i = 0; i < ARRAY_SIZE(tpr_instr); i++) {
@@@ -253,7 -255,7 +255,7 @@@ instruction_ok
       * Grab the virtual TPR address from the instruction
       * and update the cached values.
       */
-     if (cpu_memory_rw_debug(env, ip + instr->addr_offset,
+     if (cpu_memory_rw_debug(cs, ip + instr->addr_offset,
                              (void *)&real_tpr_addr,
                              sizeof(real_tpr_addr), 0) < 0) {
          return -1;
  
  static int update_rom_mapping(VAPICROMState *s, CPUX86State *env, target_ulong ip)
  {
+     CPUState *cs = CPU(x86_env_get_cpu(env));
      hwaddr paddr;
      uint32_t rom_state_vaddr;
      uint32_t pos, patch, offset;
  
      /* find out virtual address of the ROM */
      rom_state_vaddr = s->rom_state_paddr + (ip & 0xf0000000);
-     paddr = cpu_get_phys_page_debug(env, rom_state_vaddr);
+     paddr = cpu_get_phys_page_debug(cs, rom_state_vaddr);
      if (paddr == -1) {
          return -1;
      }
   * cannot be accessed or is considered invalid. This also ensures that we are
   * not patching the wrong guest.
   */
- static int get_kpcr_number(CPUX86State *env)
+ static int get_kpcr_number(X86CPU *cpu)
  {
+     CPUX86State *env = &cpu->env;
      struct kpcr {
          uint8_t  fill1[0x1c];
          uint32_t self;
          uint8_t  number;
      } QEMU_PACKED kpcr;
  
-     if (cpu_memory_rw_debug(env, env->segs[R_FS].base,
+     if (cpu_memory_rw_debug(CPU(cpu), env->segs[R_FS].base,
                              (void *)&kpcr, sizeof(kpcr), 0) < 0 ||
          kpcr.self != env->segs[R_FS].base) {
          return -1;
      return kpcr.number;
  }
  
- static int vapic_enable(VAPICROMState *s, CPUX86State *env)
+ static int vapic_enable(VAPICROMState *s, X86CPU *cpu)
  {
-     int cpu_number = get_kpcr_number(env);
+     int cpu_number = get_kpcr_number(cpu);
      hwaddr vapic_paddr;
      static const uint8_t enabled = 1;
  
          (((hwaddr)cpu_number) << VAPIC_CPU_SHIFT);
      cpu_physical_memory_rw(vapic_paddr + offsetof(VAPICState, enabled),
                             (void *)&enabled, sizeof(enabled), 1);
-     apic_enable_vapic(env->apic_state, vapic_paddr);
+     apic_enable_vapic(cpu->env.apic_state, vapic_paddr);
  
      s->state = VAPIC_ACTIVE;
  
      return 0;
  }
  
- static void patch_byte(CPUX86State *env, target_ulong addr, uint8_t byte)
+ static void patch_byte(X86CPU *cpu, target_ulong addr, uint8_t byte)
  {
-     cpu_memory_rw_debug(env, addr, &byte, 1, 1);
+     cpu_memory_rw_debug(CPU(cpu), addr, &byte, 1, 1);
  }
  
- static void patch_call(VAPICROMState *s, CPUX86State *env, target_ulong ip,
+ static void patch_call(VAPICROMState *s, X86CPU *cpu, target_ulong ip,
                         uint32_t target)
  {
      uint32_t offset;
  
      offset = cpu_to_le32(target - ip - 5);
-     patch_byte(env, ip, 0xe8); /* call near */
-     cpu_memory_rw_debug(env, ip + 1, (void *)&offset, sizeof(offset), 1);
+     patch_byte(cpu, ip, 0xe8); /* call near */
+     cpu_memory_rw_debug(CPU(cpu), ip + 1, (void *)&offset, sizeof(offset), 1);
  }
  
  static void patch_instruction(VAPICROMState *s, X86CPU *cpu, target_ulong ip)
  
      pause_all_vcpus();
  
-     cpu_memory_rw_debug(env, ip, opcode, sizeof(opcode), 0);
+     cpu_memory_rw_debug(cs, ip, opcode, sizeof(opcode), 0);
  
      switch (opcode[0]) {
      case 0x89: /* mov r32 to r/m32 */
-         patch_byte(env, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
-         patch_call(s, env, ip + 1, handlers->set_tpr);
+         patch_byte(cpu, ip, 0x50 + modrm_reg(opcode[1]));  /* push reg */
+         patch_call(s, cpu, ip + 1, handlers->set_tpr);
          break;
      case 0x8b: /* mov r/m32 to r32 */
-         patch_byte(env, ip, 0x90);
-         patch_call(s, env, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
+         patch_byte(cpu, ip, 0x90);
+         patch_call(s, cpu, ip + 1, handlers->get_tpr[modrm_reg(opcode[1])]);
          break;
      case 0xa1: /* mov abs to eax */
-         patch_call(s, env, ip, handlers->get_tpr[0]);
+         patch_call(s, cpu, ip, handlers->get_tpr[0]);
          break;
      case 0xa3: /* mov eax to abs */
-         patch_call(s, env, ip, handlers->set_tpr_eax);
+         patch_call(s, cpu, ip, handlers->set_tpr_eax);
          break;
      case 0xc7: /* mov imm32, r/m32 (c7/0) */
-         patch_byte(env, ip, 0x68);  /* push imm32 */
-         cpu_memory_rw_debug(env, ip + 6, (void *)&imm32, sizeof(imm32), 0);
-         cpu_memory_rw_debug(env, ip + 1, (void *)&imm32, sizeof(imm32), 1);
-         patch_call(s, env, ip + 5, handlers->set_tpr);
+         patch_byte(cpu, ip, 0x68);  /* push imm32 */
+         cpu_memory_rw_debug(cs, ip + 6, (void *)&imm32, sizeof(imm32), 0);
+         cpu_memory_rw_debug(cs, ip + 1, (void *)&imm32, sizeof(imm32), 1);
+         patch_call(s, cpu, ip + 5, handlers->set_tpr);
          break;
      case 0xff: /* push r/m32 */
-         patch_byte(env, ip, 0x50); /* push eax */
-         patch_call(s, env, ip + 1, handlers->get_tpr_stack);
+         patch_byte(cpu, ip, 0x50); /* push eax */
+         patch_call(s, cpu, ip + 1, handlers->get_tpr_stack);
          break;
      default:
          abort();
@@@ -458,16 -462,16 +462,16 @@@ void vapic_report_tpr_access(DeviceStat
  
      cpu_synchronize_state(cs);
  
-     if (evaluate_tpr_instruction(s, env, &ip, access) < 0) {
+     if (evaluate_tpr_instruction(s, cpu, &ip, access) < 0) {
          if (s->state == VAPIC_ACTIVE) {
-             vapic_enable(s, env);
+             vapic_enable(s, cpu);
          }
          return;
      }
      if (update_rom_mapping(s, env, ip) < 0) {
          return;
      }
-     if (vapic_enable(s, env) < 0) {
+     if (vapic_enable(s, cpu) < 0) {
          return;
      }
      patch_instruction(s, cpu, ip);
@@@ -667,8 -671,8 +671,8 @@@ static void vapic_write(void *opaque, h
               * accurate.
               */
              pause_all_vcpus();
-             patch_byte(env, env->eip - 2, 0x66);
-             patch_byte(env, env->eip - 1, 0x90);
+             patch_byte(cpu, env->eip - 2, 0x66);
+             patch_byte(cpu, env->eip - 1, 0x90);
              resume_all_vcpus();
          }
  
          if (find_real_tpr_addr(s, env) < 0) {
              break;
          }
-         vapic_enable(s, env);
+         vapic_enable(s, cpu);
          break;
      default:
      case 4:
@@@ -703,18 -707,19 +707,18 @@@ static const MemoryRegionOps vapic_ops 
      .endianness = DEVICE_NATIVE_ENDIAN,
  };
  
 -static int vapic_init(SysBusDevice *dev)
 +static void vapic_realize(DeviceState *dev, Error **errp)
  {
 +    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
      VAPICROMState *s = VAPIC(dev);
  
      memory_region_init_io(&s->io, OBJECT(s), &vapic_ops, s, "kvmvapic", 2);
 -    sysbus_add_io(dev, VAPIC_IO_PORT, &s->io);
 -    sysbus_init_ioports(dev, VAPIC_IO_PORT, 2);
 +    sysbus_add_io(sbd, VAPIC_IO_PORT, &s->io);
 +    sysbus_init_ioports(sbd, VAPIC_IO_PORT, 2);
  
      option_rom[nb_option_roms].name = "kvmvapic.bin";
      option_rom[nb_option_roms].bootindex = -1;
      nb_option_roms++;
 -
 -    return 0;
  }
  
  static void do_vapic_enable(void *data)
      VAPICROMState *s = data;
      X86CPU *cpu = X86_CPU(first_cpu);
  
-     vapic_enable(s, &cpu->env);
+     vapic_enable(s, cpu);
  }
  
  static int vapic_post_load(void *opaque, int version_id)
@@@ -811,12 -816,13 +815,12 @@@ static const VMStateDescription vmstate
  
  static void vapic_class_init(ObjectClass *klass, void *data)
  {
 -    SysBusDeviceClass *sc = SYS_BUS_DEVICE_CLASS(klass);
      DeviceClass *dc = DEVICE_CLASS(klass);
  
      dc->no_user = 1;
      dc->reset   = vapic_reset;
      dc->vmsd    = &vmstate_vapic;
 -    sc->init    = vapic_init;
 +    dc->realize = vapic_realize;
  }
  
  static const TypeInfo vapic_type = {