Esempio n. 1
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
save_irqchip()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  g_kvm_irqchip_pic_master.chip_id = KVM_IRQCHIP_PIC_MASTER;
  g_kvm_irqchip_pic_slave.chip_id = KVM_IRQCHIP_PIC_SLAVE;
  g_kvm_irqchip_ioapic.chip_id = KVM_IRQCHIP_IOAPIC;

  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_GET_IRQCHIP, &g_kvm_irqchip_pic_master);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_GET_IRQCHIP, &g_kvm_irqchip_pic_slave);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_GET_IRQCHIP, &g_kvm_irqchip_ioapic);
  if (ret < 0) {
    return ret;
  }

  return ret;
}
extern "C" int __register_atfork(void (*prepare)(void), void (*parent)(void),
                                 void (*child)(void), void *dso_handle)
{
  if (!pthread_atfork_initialized) {
    pthread_atfork_initialized = true;
    NEXT_FNC(pthread_atfork) (NULL, NULL, pidVirt_pthread_atfork_child);
  }
  return NEXT_FNC(__register_atfork)(prepare, parent, child, dso_handle);
}
Esempio n. 3
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
save_registers()
{
  int ret;
  static int (*next_fnc)() = NULL; /* Same type signature as ioctl */

  DPRINTF("Trying to get registers\n");

  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_REGS, &g_kvm_regs);
  if (ret < 0) {
    return ret;
  }

  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_XSAVE, &g_kvm_xsave);
  if (ret < 0) {
    return ret;
  }

  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_XCRS, &g_kvm_xcrs);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_SREGS, &g_kvm_sregs);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_MSRS, &g_kvm_msrs);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_MP_STATE, &g_kvm_mp_state);
  DPRINTF("************************** GOT MP STATE: %s\n",
          get_mp_state_string(g_kvm_mp_state));
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_LAPIC, &g_kvm_lapic);
  if (ret < 0) {
    return ret;
  }
#if 0
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_VCPU_EVENTS, &g_kvm_vcpu_events);
  if (ret < 0) {
    return ret;
  }
#endif /* if 0 */
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_DEBUGREGS, &g_kvm_dbgregs);
  if (ret < 0) {
    return ret;
  }

  DPRINTF("Get registers done\n");
  return 0;
}
Esempio n. 4
0
unsigned int sleep(unsigned int seconds) {
  printf("(sleep2: "); print_time(); printf(" ... ");
  unsigned int result = NEXT_FNC(sleep)(seconds);
  print_time(); printf(") ");

  return result;
}
Esempio n. 5
0
void *dlopen(const char *filename, int flag) {
  if (filename) {
    if (strstr(filename, "libibverbs.so")) {
      return RTLD_DEFAULT;
    }
  }
  return NEXT_FNC(dlopen)(filename, flag);
}
Esempio n. 6
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
create_irqchip()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  DPRINTF("Creating IRQCHIP\n");
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_CREATE_IRQCHIP, g_kvm_irqchip_arg);
  return ret;
}
Esempio n. 7
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
save_pit2()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_GET_PIT2, &g_kvm_pit2);

  return ret;
}
Esempio n. 8
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
restore_irqchip()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_IRQCHIP, &g_kvm_irqchip_pic_master);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_IRQCHIP, &g_kvm_irqchip_pic_slave);
  if (ret < 0) {
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_IRQCHIP, &g_kvm_irqchip_ioapic);
  if (ret < 0) {
    return ret;
  }

  return ret;
}
Esempio n. 9
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
restore_pit2()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_PIT2, &g_kvm_pit2);
  if (ret < 0) {
    perror("ioctl(KVM_SET_PIT2)");
  }

  return ret;
}
Esempio n. 10
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
create_pit2()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  DPRINTF("Creating PIT2\n");
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_CREATE_PIT2, &g_kvm_pit2_config);
  if (ret < 0) {
    perror("ioctl(KVM_CREATE_PIT2)");
  }
  return ret;
}
Esempio n. 11
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
restore_id_map_addr()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  DPRINTF("Setting identity map address.\n");
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_IDENTITY_MAP_ADDR, &g_kvm_id_map_addr);
  if (ret < 0) {
    DPRINTF("Could not set id-map\n");
    return ret;
  }

  return 0;
}
Esempio n. 12
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
restore_tss_addr()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  DPRINTF("Setting tss address.\n");
  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_TSS_ADDR, g_kvm_tss_addr);
  if (ret < 0) {
    DPRINTF("Could not set tss address.\n");
    return ret;
  }

  return 0;
}
Esempio n. 13
0
extern "C" void
dmtcp_initialize_plugin()
{
  // Now register the "in-built" plugins.
  dmtcp_register_plugin(dmtcp_Syslog_PluginDescr());
  dmtcp_register_plugin(dmtcp_Alarm_PluginDescr());
  dmtcp_register_plugin(dmtcp_Terminal_PluginDescr());
  dmtcp_register_plugin(dmtcp_CoordinatorAPI_PluginDescr());
  dmtcp_register_plugin(dmtcp_ProcessInfo_PluginDescr());

  void (*fn)() = NEXT_FNC(dmtcp_initialize_plugin);
  if (fn != NULL) {
    (*fn)();
  }
}
Esempio n. 14
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
create_vcpu()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  ret = NEXT_FNC(ioctl)(g_vm_fd, KVM_CREATE_VCPU, g_kvm_vcpu_arg);
  if (ret < 0) {
    return ret;
  }

  g_vcpu_fd = dup2(ret, g_vcpu_fd);
  if (g_vcpu_fd < 0) {
    return g_vcpu_fd;
  }
  return 0;
}
Esempio n. 15
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
create_vm()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */

  DPRINTF("Creating new VMFD\n");
  ret = NEXT_FNC(ioctl)(g_kvm_fd, KVM_CREATE_VM, g_kvm_vm_arg);
  if (ret < 0) {
    return ret;
  }
  g_vm_fd = dup2(ret, g_vm_fd);
  if (g_vm_fd < 0) {
    perror("dup2(): Duplicating new VMFD");
  }
  return g_vm_fd;
}
Esempio n. 16
0
File: kvm.c Progetto: dmtcp/dmtcp
/* This is the wrapper for mmap()
 *  Used for saving the params for mmap of vcpu fd
 */
void *
mmap64(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
{
  static void *(*next_fnc)() = NULL;

  void *result = NEXT_FNC(mmap)(addr, length, prot, flags,
                                fd, offset);

  if (fd == g_vcpu_fd) {
    DPRINTF("Saving the vcpu mmap64 params. addr: %p, length: %zu, prot: %d, "
            "flags: %d, offset: %ld\n",
            addr, length, prot, flags, (long)offset);
    g_vcpu_mmap_addr = result;
    g_vcpu_mmap_prot = prot;
    g_vcpu_mmap_length = length;
    g_vcpu_mmap_flags = flags;

    /* NOTE: The offset is assumed to be zero. */
  }
  return result;
}
Esempio n. 17
0
File: tun.c Progetto: dmtcp/dmtcp
int
open64(const char *pathname, int flags, ...)
{
  va_list argp;
  static int (*next_fnc)() = NULL; /* Same type signature as open */
  mode_t mode = 0;
  int result;

  if (flags & O_CREAT) {
    va_list arg;
    va_start(arg, flags);
    mode = va_arg(arg, int);
    va_end(arg);
  }

  result = NEXT_FNC(open)(pathname, flags, mode);

  /* Check if the process is opening a connection to the tun driver */
  if (!strncmp(pathname, "/dev/net/tun", 13)) {
    /* Save the file descriptor if it is the tun driver
     * NOTE: This will overwrite the last saved fd (if any).
     */
    g_tun_fd = result;
    DPRINTF("[%s:%d]: PARAMS: pathname: %s, flags:%d; Result: %d\n",
            __FUNCTION__, __LINE__, pathname, flags, g_tun_fd);
  }
  return result;
}

/* TODO: Fix this duplicate */
int
Esempio n. 18
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
save_supported_msrs()
{
  int ret;

  /* IMPORTANT: See note for KVM_GET_MSRS below in the ioctl wrapper. */
#if 0
  int i, n;

  n = 0;
  g_kvm_msrs.entries[n++].index = MSR_IA32_SYSENTER_CS;
  g_kvm_msrs.entries[n++].index = MSR_IA32_SYSENTER_ESP;
  g_kvm_msrs.entries[n++].index = MSR_IA32_SYSENTER_EIP;
  g_kvm_msrs.entries[n++].index = MSR_PAT;
  if (has_msr_star) {
    g_kvm_msrs.entries[n++].index = MSR_STAR;
  }
  if (has_msr_hsave_pa) {
    g_kvm_msrs.entries[n++].index = MSR_VM_HSAVE_PA;
  }
  if (has_msr_tsc_deadline) {
    g_kvm_msrs.entries[n++].index = MSR_IA32_TSCDEADLINE;
  }
  if (has_msr_misc_enable) {
    g_kvm_msrs.entries[n++].index = MSR_IA32_MISC_ENABLE;
  }

  if (!env->tsc_valid) {
    g_kvm_msrs.entries[n++].index = MSR_IA32_TSC;
    env->tsc_valid = !runstate_is_running();
  }

  if (long_mode_supported) {
    g_kvm_msrs.entries[n++].index = MSR_CSTAR;
    g_kvm_msrs.entries[n++].index = MSR_KERNELGSBASE;
    g_kvm_msrs.entries[n++].index = MSR_FMASK;
    g_kvm_msrs.entries[n++].index = MSR_LSTAR;
  }
  g_kvm_msrs.entries[n++].index = MSR_KVM_SYSTEM_TIME;
  g_kvm_msrs.entries[n++].index = MSR_KVM_WALL_CLOCK;
  if (has_msr_async_pf_en) {
    g_kvm_msrs.entries[n++].index = MSR_KVM_ASYNC_PF_EN;
  }
  if (has_msr_pv_eoi_en) {
    g_kvm_msrs.entries[n++].index = MSR_KVM_PV_EOI_EN;
  }

  if (env->mcg_cap) {
    g_kvm_msrs.entries[n++].index = MSR_MCG_STATUS;
    g_kvm_msrs.entries[n++].index = MSR_MCG_CTL;
    for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) {
      g_kvm_msrs.entries[n++].index = MSR_MC0_CTL + i;
    }
  }

  g_kvm_msrs.info.nmsrs = n;
#endif /* if 0 */
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_GET_MSRS, &g_kvm_msrs);
  if (ret < 0) {
    return ret;
  }

  return 0;
}
Esempio n. 19
0
File: kvm.c Progetto: dmtcp/dmtcp
static void
restart()
{
  int r;

  DPRINTF("Restarting from checkpoint.\n");
  if (g_kvm_fd > 0 && g_vm_fd > 0 && g_vcpu_fd > 0) {
    r = create_vm();
    if (r < 0) {
      DPRINTF("ERROR: Creating VMFD returned: %d\n", r);
      DPRINTF("WARNING: Please try checkpointing again\n");
      exit(-1);
    } else if (r > 0) {
      int i = 0;
      int t = 0;

      r = restore_id_map_addr();
      if (r < 0) {
        DPRINTF("ERROR: Restoring identity map addr returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }
      r = restore_tss_addr();
      if (r < 0) {
        DPRINTF("ERROR: Restoring tss addr returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }
      r = create_irqchip();
      if (r < 0) {
        DPRINTF("ERROR: Creating IRQCHIP returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }

      r = create_vcpu();
      if (r < 0) {
        DPRINTF("ERROR: Creating new VCPU returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      if (NEXT_FNC(mmap)(g_vcpu_mmap_addr, g_vcpu_mmap_length,
                         g_vcpu_mmap_prot, g_vcpu_mmap_flags | MAP_FIXED,
                         g_vcpu_fd, 0) == MAP_FAILED) {
        DPRINTF("ERROR: Mapping the new VCPU returned MAP_FAILED\n");
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_SIGNAL_MASK, &g_kvm_sigmask);
      if (r < 0) {
        DPRINTF("ERROR: Setting VCPU Signal Mask returned: %d\n", r);
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_IRQ_LINE_STATUS, &g_kvm_irq_level);
      if (r < 0) {
        DPRINTF("ERROR: Setting IRQ LINE status returned: %d\n", r);
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_REGISTER_COALESCED_MMIO,
                          &g_kvm_coalesced_mmio_zone);
      if (r < 0) {
        DPRINTF("ERROR: Setting Coalesced MMIO Zone returned: %d\n", r);
        exit(-1);
      }

      DPRINTF("Setting #%d memory regions\n", g_num_of_memory_regions);
      struct kvm_userspace_memory_region *mem;
      for (i = 0; i < g_num_of_memory_regions; i++) {
        mem = &g_kvm_mem_region[i];
        DPRINTF("slot:%X, flags:%X, start:%llX, size:%llX, ram:%llX)\n",
                mem->slot, mem->flags, mem->guest_phys_addr,
                mem->memory_size, mem->userspace_addr);
        r = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_USER_MEMORY_REGION,
                            &g_kvm_mem_region[i]);
        if (r < 0) {
          DPRINTF("ERROR: Creating memory region #%d returned: \n", i, r);
          perror("ioctl(KVM_SET_USER_MEMORY_REGION)");
        }
      }

      /* See note in the ioctl() wrapper. */
      DPRINTF("Setting routing tables. ptr: %p...\n",
              g_kvm_gsi_routing_table);
      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_GSI_ROUTING,
                          g_kvm_gsi_routing_table);
      if (r < 0) {
        DPRINTF("ERROR: Setting routing table (#routes=%d) returned: "
                "%d\n", g_kvm_gsi_routing_table->nr, r);
      }

      r = create_pit2();
      if (r < 0) {
        DPRINTF("Creating PIT2 returned: %d\n", r);
      }
      r = restore_pit2();
      if (r < 0) {
        DPRINTF("ERROR: Restoring PIT2 returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      int array[] = { 0, 1, 4, 8, 12 };
      g_kvm_irq_level.level = 0;
      for (i = 0; i < 5; i++) {
        g_kvm_irq_level.irq = array[i];
        r = NEXT_FNC(ioctl)(g_vm_fd, KVM_IRQ_LINE_STATUS, &g_kvm_irq_level);
        if (r < 0) {
          DPRINTF("ERROR: Resetting IRQ#%d LINE returned: %d\n",
                  g_kvm_irq_level.irq,
                  r);
          exit(-1);
        }
      }
      r = restore_irqchip();
      if (r < 0) {
        DPRINTF("ERROR: Restoring IRQCHIP returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_TPR_ACCESS_REPORTING,
                          &g_kvm_tpr_access_ctl);
      if (r < 0) {
        DPRINTF("ERROR: Restoring the tpr access reporting returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_VAPIC_ADDR,
                          &g_kvm_vapic_addr);
      if (r < 0) {
        DPRINTF("ERROR: Restoring the vapic addr returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = restore_registers();
      if (r < 0) {
        DPRINTF("ERROR: Restoring the registers returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
    }
  }
}
Esempio n. 20
0
File: kvm.c Progetto: dmtcp/dmtcp
/*
 * This is the wrapper for ioctl()
 *  Assumption: QEMU makes three argument ioctl calls to KVM. This will need to
 *              be changed if this assumption is broken.
 *  NOTE: The man page (and POSIX) says that the request type is signed int, but
 *        the Linux kernel, and glibc all treat it as unsigned.
 */
int
ioctl(int fd, unsigned long int request, ...)
{
  va_list argp;
  static int (*next_fnc)() = NULL; /* Same type signature as ioctl */
  static int p_first_get_msr_index_list_call = 1;
  int result;
  void *arg;
  static int init = 1;
  static int init2 = 1;

  va_start(argp, request);
  arg = va_arg(argp, void *);
  va_end(argp);
  result = NEXT_FNC(ioctl)(fd, request, arg);

  /* This is NOT a hack. Kernel declares/defines it as an unsigned int. Glibc
   * for some reason decided to declare/define it as unsigned long. GCC-4.7.3
   * does a sign-extension by default which results in wrong values.
   * See http://sourceware.org/bugzilla/show_bug.cgi?id=14362 */
  switch ((unsigned int)request) {
  case KVM_CREATE_VM:
  {
    DPRINTF("Saving KVM VM. arg: %p\n", arg);
    g_kvm_fd = fd;
    g_vm_fd = result;
    g_kvm_vm_arg = arg;
    DPRINTF("Got VMFD: %u\n", g_vm_fd);
    break;
  }
  case KVM_CREATE_VCPU:
  {
    DPRINTF("Saving KVM VCPU. arg: %p\n", arg);
    g_vcpu_fd = result;
    g_kvm_vcpu_arg = arg;
    DPRINTF("Got VCPUFD %u\n", g_vcpu_fd);
    break;
  }
  case KVM_GET_MSRS:
  {
    /* NOTE: We rely on QEMU to make this call to get to know the supported
     *       msrs, which it must have determined using the
     *       KVM_GET_MSR_INDEX_LIST call at init. This saves us some cycles
     *       but it will fail if QEMU never makes the KVM_GET_MSRS call.
     */
    if (fd == g_vcpu_fd) {
      DPRINTF("Saving supported MSRS from QEMU\n");
      memcpy(&g_kvm_msrs, arg, sizeof(g_kvm_msrs));
    }
    break;
  }
  case KVM_SET_SIGNAL_MASK:
  {
    memcpy(&g_kvm_sigmask, arg, SIGMASK_SIZE);
    break;
  }
  case KVM_REGISTER_COALESCED_MMIO:
  {
    memcpy(&g_kvm_coalesced_mmio_zone, arg, sizeof(g_kvm_coalesced_mmio_zone));
    break;
  }
  case KVM_TPR_ACCESS_REPORTING:
  {
    memcpy(&g_kvm_tpr_access_ctl, arg, sizeof(g_kvm_tpr_access_ctl));
    break;
  }
  case KVM_SET_VCPU_EVENTS:
  {
    if (init) {
      memcpy(&g_kvm_vcpu_events, arg, sizeof(g_kvm_vcpu_events));
      init = 0;
    }
    break;
  }
  case KVM_IRQ_LINE_STATUS:
  {
    // memcpy(&g_kvm_irq_level, arg, sizeof(g_kvm_irq_level));
    // DPRINTF("Setting IRQ Line: %u, Level: %u\n", g_kvm_irq_level.irq,
    // g_kvm_irq_level.level);
    break;
  }
  case KVM_SET_MP_STATE:
  {
    DPRINTF("******************************* Setting MP State to: %s\n",
            get_mp_state_string(*(struct kvm_mp_state *)arg));
    break;
  }
  case KVM_GET_MP_STATE:
  {
    DPRINTF("******************************* Kernel's MP State is: %s\n",
            get_mp_state_string(*(struct kvm_mp_state *)arg));
    break;
  }
  case KVM_SET_LAPIC:
  {
    if (init2) {
      memcpy(&g_kvm_lapic, arg, sizeof(g_kvm_lapic));
      init2 = 0;
    }
    break;
  }
  case KVM_GET_LAPIC:
  {
    DPRINTF("############################### Kernel's LAPIC State\n");
    break;
  }
#if 0

  /* NOTE: We are skipping this... see note for KVM_GET_MSRS above. */
  case KVM_GET_MSR_INDEX_LIST:
  {
    /* The first call is to query the number of MSRs */
    if (p_first_get_msr_index_list_call) {
      DPRINTF("Saving MSR Index List (1/2). arg: %p", arg);
      p_first_get_msr_index_list_call = 0;
    } else {
      /* The subsequent call gives us the actual MSR list */
      DPRINTF("Saving MSR Index List (2/2). arg: %p", arg);
    }
    break;
  }
#endif /* if 0 */
  case KVM_CREATE_PIT2:
  {
    if (fd == g_vm_fd) {
      DPRINTF("Saving PIT2 config. arg: %p\n", arg);
      memcpy(&g_kvm_pit2_config, arg, sizeof(g_kvm_pit2_config));
    }
    break;
  }
  case KVM_SET_IDENTITY_MAP_ADDR:
  {
    DPRINTF("Saving identity map address. arg: %p\n", arg);

    /* Kernel does a copy_from_user() of sizeof(uint64_t) bytes for this addr */
    memcpy(&g_kvm_id_map_addr, arg, sizeof(g_kvm_id_map_addr));
    DPRINTF("IOCTL returned %u\n", result);
    break;
  }
  case KVM_SET_TSS_ADDR:
  {
    DPRINTF("Saving tss address. arg: %p\n", arg);

    /* Kernel uses this value as an (unsigned int) directly */
    g_kvm_tss_addr = arg;
    DPRINTF("IOCTL returned %u\n", result);
    break;
  }
  case KVM_SET_USER_MEMORY_REGION:
  {
    if (fd == g_vm_fd) {
      struct kvm_userspace_memory_region mem;

      /* We don't handle more than MAX_MEM_REGIONS memory regions;
       * will need to make it dynamic to handle all possible cases. */
      DPRINTF("Saving user memory region #%d\n", g_num_of_memory_regions);

      // memcpy(&mem, arg, sizeof(struct kvm_userspace_memory_region));
      process_memory_region(arg);
    }
    break;
  }
  case KVM_CREATE_IRQCHIP:
  {
    DPRINTF("Saving irqchip address. arg: %p\n", arg);

    /* This is not relevant; might as well skip this. See the kernel code
     * (in arch/x86/kvm/x86.c) for more details. */
    g_kvm_irqchip_arg = arg;
    DPRINTF("IOCTL returned %u\n", result);
    break;
  }
  case KVM_SET_VAPIC_ADDR:
  {
    DPRINTF("Saving virtual APIC address. arg: %p\n", arg);

    /* Kernel does a copy_from_user() of sizeof(struct kvm_vapic_addr)
     * bytes. See the code in arch/x86/kvm/x86.c for more details. */
    memcpy(&g_kvm_vapic_addr, arg, sizeof(g_kvm_vapic_addr));
    DPRINTF("IOCTL returned %u\n", result);
    break;
  }
  case KVM_SET_GSI_ROUTING:
  {
    DPRINTF("Saving GSI routing table. Routing table address: %p, "
            "count: %d\n", arg, ((struct kvm_irq_routing *)arg)->nr);

    /* NOTE:
     *  a) QEMU uses address of a global struct to store the GSI routing
     *      table. We use the hack below to save us from copying over the
     *      data again.
     *  b) This struct is re-alloced to twice its previous size within QEMU
     *      each time it reaches the limit.
     *  c) Kernel looks at the number of entries (routing_table.nr), and
     *      does a copy_from_user() of routing_table.nr * sizeof(entry)
     *      bytes.
     *  d) As a result, we get away with a single ioctl(KVM_SET_GSI_ROUTING)
     *      call at the time of restart.
     * IMPORTANT: If (a), or (c) breaks, this code will be invalid.
     */
    g_kvm_gsi_routing_table = arg;
    break;
  }
  }

  return result;
}
Esempio n. 21
0
File: kvm.c Progetto: dmtcp/dmtcp
static int
restore_registers()
{
  int ret;
  static int (*next_fnc)() = NULL; /* same type signature as ioctl */


  DPRINTF("Trying to put registers\n");

  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_REGS, &g_kvm_regs);
  if (ret < 0) {
    perror("ioctl(KVM_SET_REGS)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_XSAVE, &g_kvm_xsave);
  if (ret < 0) {
    perror("ioctl(KVM_SET_XSAVE)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_XCRS, &g_kvm_xcrs);
  if (ret < 0) {
    perror("ioctl(KVM_SET_XCRS)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_SREGS, &g_kvm_sregs);
  if (ret < 0) {
    perror("ioctl(KVM_SET_SREGS)");
    return ret;
  }

  /* must be before kvm_put_msrs */
  ret = inject_mce();
  if (ret < 0) {
    perror("ioctl(KVM_SET_MCE)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_MSRS, &g_kvm_msrs);
  if (ret < 0) {
    perror("ioctl(KVM_SET_MSRS)");
    return ret;
  }

  // DPRINTF("Not setting MP State to: %s\n",
  // get_mp_state_string(g_kvm_mp_state));
#if 0
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_MP_STATE, &g_kvm_mp_state);
  if (ret < 0) {
    perror("ioctl(KVM_SET_MP_STATE)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_LAPIC, &g_kvm_lapic);
  if (ret < 0) {
    perror("ioctl(KVM_SET_LAPIC)");
    return ret;
  }
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_VCPU_EVENTS, &g_kvm_vcpu_events);
  if (ret < 0) {
    perror("ioctl(KVM_SET_VCPU_EVENTS)");
    return ret;
  }
#endif /* if 0 */
  ret = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_DEBUGREGS, &g_kvm_dbgregs);
  if (ret < 0) {
    perror("ioctl(KVM_SET_DEBUGREGS)");
    return ret;
  }

  /* must be last */

  /*
  ret = kvm_guest_debug_workarounds();
  if (ret < 0) {
    return ret;
  }
  */
  DPRINTF("Put registers done\n");
  return 0;
}