Diff for /qemu/kqemu.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2018/04/24 16:44:43 version 1.1.1.5, 2018/04/24 16:47:04
Line 1 Line 1
 /*  /*
  *  KQEMU support   *  KQEMU support
  *    *
  *  Copyright (c) 2005 Fabrice Bellard   *  Copyright (c) 2005 Fabrice Bellard
  *   *
  * This library is free software; you can redistribute it and/or   * This library is free software; you can redistribute it and/or
Line 19 Line 19
  */   */
 #include "config.h"  #include "config.h"
 #ifdef _WIN32  #ifdef _WIN32
   #define WIN32_LEAN_AND_MEAN
 #include <windows.h>  #include <windows.h>
 #include <winioctl.h>  #include <winioctl.h>
 #else  #else
Line 27 Line 28
 #include <sys/ioctl.h>  #include <sys/ioctl.h>
 #endif  #endif
 #ifdef HOST_SOLARIS  #ifdef HOST_SOLARIS
 #include <sys/modctl.h>  #include <sys/ioccom.h>
 #endif  #endif
 #include <stdlib.h>  #include <stdlib.h>
 #include <stdio.h>  #include <stdio.h>
Line 129  static void kqemu_update_cpuid(CPUState  Line 130  static void kqemu_update_cpuid(CPUState 
        target cpus because they are important for user code. Strictly         target cpus because they are important for user code. Strictly
        speaking, only SSE really matters because the OS must support         speaking, only SSE really matters because the OS must support
        it if the user code uses it. */         it if the user code uses it. */
     critical_features_mask =       critical_features_mask =
         CPUID_CMOV | CPUID_CX8 |           CPUID_CMOV | CPUID_CX8 |
         CPUID_FXSR | CPUID_MMX | CPUID_SSE |           CPUID_FXSR | CPUID_MMX | CPUID_SSE |
         CPUID_SSE2 | CPUID_SEP;          CPUID_SSE2 | CPUID_SEP;
     ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;      ext_features_mask = CPUID_EXT_SSE3 | CPUID_EXT_MONITOR;
     if (!is_cpuid_supported()) {      if (!is_cpuid_supported()) {
Line 177  int kqemu_init(CPUState *env) Line 178  int kqemu_init(CPUState *env)
     kqemu_fd = open(KQEMU_DEVICE, O_RDWR);      kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
 #endif  #endif
     if (kqemu_fd == KQEMU_INVALID_FD) {      if (kqemu_fd == KQEMU_INVALID_FD) {
         fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated\n", KQEMU_DEVICE);          fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
                   KQEMU_DEVICE, strerror(errno));
         return -1;          return -1;
     }      }
     version = 0;      version = 0;
Line 193  int kqemu_init(CPUState *env) Line 195  int kqemu_init(CPUState *env)
         goto fail;          goto fail;
     }      }
   
     pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *       pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
                                   sizeof(unsigned long));                                    sizeof(unsigned long));
     if (!pages_to_flush)      if (!pages_to_flush)
         goto fail;          goto fail;
   
     ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *       ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *
                                        sizeof(unsigned long));                                         sizeof(unsigned long));
     if (!ram_pages_to_update)      if (!ram_pages_to_update)
         goto fail;          goto fail;
   
     modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *       modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *
                                       sizeof(unsigned long));                                        sizeof(unsigned long));
     if (!modified_ram_pages)      if (!modified_ram_pages)
         goto fail;          goto fail;
Line 285  static void kqemu_reset_modified_ram_pag Line 287  static void kqemu_reset_modified_ram_pag
 {  {
     int i;      int i;
     unsigned long page_index;      unsigned long page_index;
       
     for(i = 0; i < nb_modified_ram_pages; i++) {      for(i = 0; i < nb_modified_ram_pages; i++) {
         page_index = modified_ram_pages[i] >> TARGET_PAGE_BITS;          page_index = modified_ram_pages[i] >> TARGET_PAGE_BITS;
         modified_ram_pages_table[page_index] = 0;          modified_ram_pages_table[page_index] = 0;
Line 311  void kqemu_modify_page(CPUState *env, ra Line 313  void kqemu_modify_page(CPUState *env, ra
         if (nb_modified_ram_pages >= KQEMU_MAX_MODIFIED_RAM_PAGES) {          if (nb_modified_ram_pages >= KQEMU_MAX_MODIFIED_RAM_PAGES) {
             /* flush */              /* flush */
 #ifdef _WIN32  #ifdef _WIN32
             ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,               ret = DeviceIoControl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
                                   &nb_modified_ram_pages,                                     &nb_modified_ram_pages,
                                   sizeof(nb_modified_ram_pages),                                    sizeof(nb_modified_ram_pages),
                                   NULL, 0, &temp, NULL);                                    NULL, 0, &temp, NULL);
 #else  #else
             ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,               ret = ioctl(kqemu_fd, KQEMU_MODIFY_RAM_PAGES,
                         &nb_modified_ram_pages);                          &nb_modified_ram_pages);
 #endif  #endif
             kqemu_reset_modified_ram_pages();              kqemu_reset_modified_ram_pages();
Line 363  static void restore_native_fp_frstor(CPU Line 365  static void restore_native_fp_frstor(CPU
 {  {
     int fptag, i, j;      int fptag, i, j;
     struct fpstate fp1, *fp = &fp1;      struct fpstate fp1, *fp = &fp1;
       
     fp->fpuc = env->fpuc;      fp->fpuc = env->fpuc;
     fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;      fp->fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
     fptag = 0;      fptag = 0;
Line 383  static void restore_native_fp_frstor(CPU Line 385  static void restore_native_fp_frstor(CPU
     }      }
     asm volatile ("frstor %0" : "=m" (*fp));      asm volatile ("frstor %0" : "=m" (*fp));
 }  }
    
 static void save_native_fp_fsave(CPUState *env)  static void save_native_fp_fsave(CPUState *env)
 {  {
     int fptag, i, j;      int fptag, i, j;
Line 469  static int do_syscall(CPUState *env, Line 471  static int do_syscall(CPUState *env,
                       struct kqemu_cpu_state *kenv)                        struct kqemu_cpu_state *kenv)
 {  {
     int selector;      int selector;
       
     selector = (env->star >> 32) & 0xffff;      selector = (env->star >> 32) & 0xffff;
 #ifdef __x86_64__  #ifdef __x86_64__
     if (env->hflags & HF_LMA_MASK) {      if (env->hflags & HF_LMA_MASK) {
Line 481  static int do_syscall(CPUState *env, Line 483  static int do_syscall(CPUState *env,
         code64 = env->hflags & HF_CS64_MASK;          code64 = env->hflags & HF_CS64_MASK;
   
         cpu_x86_set_cpl(env, 0);          cpu_x86_set_cpl(env, 0);
         cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,           cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
                                0, 0xffffffff,                                  0, 0xffffffff,
                                DESC_G_MASK | DESC_P_MASK |                                 DESC_G_MASK | DESC_P_MASK |
                                DESC_S_MASK |                                 DESC_S_MASK |
                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);                                 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK | DESC_L_MASK);
         cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,           cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
                                0, 0xffffffff,                                 0, 0xffffffff,
                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |                                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                                DESC_S_MASK |                                 DESC_S_MASK |
Line 496  static int do_syscall(CPUState *env, Line 498  static int do_syscall(CPUState *env,
             env->eip = env->lstar;              env->eip = env->lstar;
         else          else
             env->eip = env->cstar;              env->eip = env->cstar;
     } else       } else
 #endif  #endif
     {      {
         env->regs[R_ECX] = (uint32_t)kenv->next_eip;          env->regs[R_ECX] = (uint32_t)kenv->next_eip;
           
         cpu_x86_set_cpl(env, 0);          cpu_x86_set_cpl(env, 0);
         cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,           cpu_x86_load_seg_cache(env, R_CS, selector & 0xfffc,
                            0, 0xffffffff,                              0, 0xffffffff,
                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |                                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                                DESC_S_MASK |                                 DESC_S_MASK |
                                DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);                                 DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);
         cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,           cpu_x86_load_seg_cache(env, R_SS, (selector + 8) & 0xfffc,
                                0, 0xffffffff,                                 0, 0xffffffff,
                                DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |                                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |
                                DESC_S_MASK |                                 DESC_S_MASK |
Line 604  void kqemu_record_dump(void) Line 606  void kqemu_record_dump(void)
         }          }
     }      }
     qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);      qsort(pr, nb_pc_records, sizeof(PCRecord *), pc_rec_cmp);
       
     f = fopen("/tmp/kqemu.stats", "w");      f = fopen("/tmp/kqemu.stats", "w");
     if (!f) {      if (!f) {
         perror("/tmp/kqemu.stats");          perror("/tmp/kqemu.stats");
Line 615  void kqemu_record_dump(void) Line 617  void kqemu_record_dump(void)
     for(i = 0; i < nb_pc_records; i++) {      for(i = 0; i < nb_pc_records; i++) {
         r = pr[i];          r = pr[i];
         sum += r->count;          sum += r->count;
         fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",           fprintf(f, "%08lx: %" PRId64 " %0.2f%% %0.2f%%\n",
                 r->pc,                   r->pc,
                 r->count,                   r->count,
                 (double)r->count / (double)total * 100.0,                  (double)r->count / (double)total * 100.0,
                 (double)sum / (double)total * 100.0);                  (double)sum / (double)total * 100.0);
     }      }
Line 696  int kqemu_cpu_exec(CPUState *env) Line 698  int kqemu_cpu_exec(CPUState *env)
     kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;      kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
 #endif  #endif
     nb_ram_pages_to_update = 0;      nb_ram_pages_to_update = 0;
       
 #if KQEMU_VERSION >= 0x010300  #if KQEMU_VERSION >= 0x010300
     kenv->nb_modified_ram_pages = nb_modified_ram_pages;      kenv->nb_modified_ram_pages = nb_modified_ram_pages;
 #endif  #endif
Line 788  int kqemu_cpu_exec(CPUState *env) Line 790  int kqemu_cpu_exec(CPUState *env)
     {      {
         unsigned int new_hflags;          unsigned int new_hflags;
 #ifdef TARGET_X86_64  #ifdef TARGET_X86_64
         if ((env->hflags & HF_LMA_MASK) &&           if ((env->hflags & HF_LMA_MASK) &&
             (env->segs[R_CS].flags & DESC_L_MASK)) {              (env->segs[R_CS].flags & DESC_L_MASK)) {
             /* long mode */              /* long mode */
             new_hflags = HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;              new_hflags = HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;
Line 800  int kqemu_cpu_exec(CPUState *env) Line 802  int kqemu_cpu_exec(CPUState *env)
                 >> (DESC_B_SHIFT - HF_CS32_SHIFT);                  >> (DESC_B_SHIFT - HF_CS32_SHIFT);
             new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)              new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
                 >> (DESC_B_SHIFT - HF_SS32_SHIFT);                  >> (DESC_B_SHIFT - HF_SS32_SHIFT);
             if (!(env->cr[0] & CR0_PE_MASK) ||               if (!(env->cr[0] & CR0_PE_MASK) ||
                    (env->eflags & VM_MASK) ||                     (env->eflags & VM_MASK) ||
                    !(env->hflags & HF_CS32_MASK)) {                     !(env->hflags & HF_CS32_MASK)) {
                 /* XXX: try to avoid this test. The problem comes from the                  /* XXX: try to avoid this test. The problem comes from the
Line 810  int kqemu_cpu_exec(CPUState *env) Line 812  int kqemu_cpu_exec(CPUState *env)
                    translate-i386.c. */                     translate-i386.c. */
                 new_hflags |= HF_ADDSEG_MASK;                  new_hflags |= HF_ADDSEG_MASK;
             } else {              } else {
                 new_hflags |= ((env->segs[R_DS].base |                   new_hflags |= ((env->segs[R_DS].base |
                                 env->segs[R_ES].base |                                  env->segs[R_ES].base |
                                 env->segs[R_SS].base) != 0) <<                                   env->segs[R_SS].base) != 0) <<
                     HF_ADDSEG_SHIFT;                      HF_ADDSEG_SHIFT;
             }              }
         }          }
         env->hflags = (env->hflags &           env->hflags = (env->hflags &
            ~(HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)) |             ~(HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)) |
             new_hflags;              new_hflags;
     }      }
Line 827  int kqemu_cpu_exec(CPUState *env) Line 829  int kqemu_cpu_exec(CPUState *env)
         env->hflags |= HF_OSFXSR_MASK;          env->hflags |= HF_OSFXSR_MASK;
     else      else
         env->hflags &= ~HF_OSFXSR_MASK;          env->hflags &= ~HF_OSFXSR_MASK;
           
 #ifdef DEBUG  #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {      if (loglevel & CPU_LOG_INT) {
         fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);          fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
Line 836  int kqemu_cpu_exec(CPUState *env) Line 838  int kqemu_cpu_exec(CPUState *env)
     if (ret == KQEMU_RET_SYSCALL) {      if (ret == KQEMU_RET_SYSCALL) {
         /* syscall instruction */          /* syscall instruction */
         return do_syscall(env, kenv);          return do_syscall(env, kenv);
     } else       } else
     if ((ret & 0xff00) == KQEMU_RET_INT) {      if ((ret & 0xff00) == KQEMU_RET_INT) {
         env->exception_index = ret & 0xff;          env->exception_index = ret & 0xff;
         env->error_code = 0;          env->error_code = 0;
Line 847  int kqemu_cpu_exec(CPUState *env) Line 849  int kqemu_cpu_exec(CPUState *env)
 #endif  #endif
 #ifdef DEBUG  #ifdef DEBUG
         if (loglevel & CPU_LOG_INT) {          if (loglevel & CPU_LOG_INT) {
             fprintf(logfile, "kqemu: interrupt v=%02x:\n",               fprintf(logfile, "kqemu: interrupt v=%02x:\n",
                     env->exception_index);                      env->exception_index);
             cpu_dump_state(env, logfile, fprintf, 0);              cpu_dump_state(env, logfile, fprintf, 0);
         }          }
Line 879  int kqemu_cpu_exec(CPUState *env) Line 881  int kqemu_cpu_exec(CPUState *env)
         }          }
 #endif  #endif
         return 0;          return 0;
     } else if (ret == KQEMU_RET_SOFTMMU) {       } else if (ret == KQEMU_RET_SOFTMMU) {
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
         {          {
             unsigned long pc = env->eip + env->segs[R_CS].base;              unsigned long pc = env->eip + env->segs[R_CS].base;
Line 903  int kqemu_cpu_exec(CPUState *env) Line 905  int kqemu_cpu_exec(CPUState *env)
 void kqemu_cpu_interrupt(CPUState *env)  void kqemu_cpu_interrupt(CPUState *env)
 {  {
 #if defined(_WIN32) && KQEMU_VERSION >= 0x010101  #if defined(_WIN32) && KQEMU_VERSION >= 0x010101
     /* cancelling the I/O request causes KQEMU to finish executing the       /* cancelling the I/O request causes KQEMU to finish executing the
        current block and successfully returning. */         current block and successfully returning. */
     CancelIo(kqemu_fd);      CancelIo(kqemu_fd);
 #endif  #endif

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


unix.superglobalmegacorp.com