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

version 1.1.1.5, 2018/04/24 16:47:04 version 1.1.1.6, 2018/04/24 16:50:18
Line 1 Line 1
 /*  /*
  *  KQEMU support   *  KQEMU support
  *   *
  *  Copyright (c) 2005 Fabrice Bellard   *  Copyright (c) 2005-2008 Fabrice Bellard
  *   *
  * This library is free software; you can redistribute it and/or   * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public   * modify it under the terms of the GNU Lesser General Public
Line 15 Line 15
  *   *
  * You should have received a copy of the GNU Lesser General Public   * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software   * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
  */   */
 #include "config.h"  #include "config.h"
 #ifdef _WIN32  #ifdef _WIN32
Line 40 Line 40
   
 #include "cpu.h"  #include "cpu.h"
 #include "exec-all.h"  #include "exec-all.h"
   #include "qemu-common.h"
   
 #ifdef USE_KQEMU  #ifdef USE_KQEMU
   
 #define DEBUG  #define DEBUG
 //#define PROFILE  //#define PROFILE
   
   
   #ifdef DEBUG
   #  define LOG_INT(...) qemu_log_mask(CPU_LOG_INT, ## __VA_ARGS__)
   #  define LOG_INT_STATE(env) log_cpu_state_mask(CPU_LOG_INT, (env), 0)
   #else
   #  define LOG_INT(...) do { } while (0)
   #  define LOG_INT_STATE(env) do { } while (0)
   #endif
   
 #include <unistd.h>  #include <unistd.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include "kqemu.h"  #include "kqemu.h"
   
 /* compatibility stuff */  
 #ifndef KQEMU_RET_SYSCALL  
 #define KQEMU_RET_SYSCALL   0x0300 /* syscall insn */  
 #endif  
 #ifndef KQEMU_MAX_RAM_PAGES_TO_UPDATE  
 #define KQEMU_MAX_RAM_PAGES_TO_UPDATE 512  
 #define KQEMU_RAM_PAGES_UPDATE_ALL (KQEMU_MAX_RAM_PAGES_TO_UPDATE + 1)  
 #endif  
 #ifndef KQEMU_MAX_MODIFIED_RAM_PAGES  
 #define KQEMU_MAX_MODIFIED_RAM_PAGES 512  
 #endif  
   
 #ifdef _WIN32  #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"  #define KQEMU_DEVICE "\\\\.\\kqemu"
 #else  #else
 #define KQEMU_DEVICE "/dev/kqemu"  #define KQEMU_DEVICE "/dev/kqemu"
 #endif  #endif
   
   static void qpi_init(void);
   
 #ifdef _WIN32  #ifdef _WIN32
 #define KQEMU_INVALID_FD INVALID_HANDLE_VALUE  #define KQEMU_INVALID_FD INVALID_HANDLE_VALUE
 HANDLE kqemu_fd = KQEMU_INVALID_FD;  HANDLE kqemu_fd = KQEMU_INVALID_FD;
Line 83  int kqemu_fd = KQEMU_INVALID_FD; Line 83  int kqemu_fd = KQEMU_INVALID_FD;
    2 = kernel kqemu     2 = kernel kqemu
 */  */
 int kqemu_allowed = 1;  int kqemu_allowed = 1;
 unsigned long *pages_to_flush;  uint64_t *pages_to_flush;
 unsigned int nb_pages_to_flush;  unsigned int nb_pages_to_flush;
 unsigned long *ram_pages_to_update;  uint64_t *ram_pages_to_update;
 unsigned int nb_ram_pages_to_update;  unsigned int nb_ram_pages_to_update;
 unsigned long *modified_ram_pages;  uint64_t *modified_ram_pages;
 unsigned int nb_modified_ram_pages;  unsigned int nb_modified_ram_pages;
 uint8_t *modified_ram_pages_table;  uint8_t *modified_ram_pages_table;
 extern uint32_t **l1_phys_map;  int qpi_io_memory;
   uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
   
 #define cpuid(index, eax, ebx, ecx, edx) \  #define cpuid(index, eax, ebx, ecx, edx) \
   asm volatile ("cpuid" \    asm volatile ("cpuid" \
Line 160  static void kqemu_update_cpuid(CPUState  Line 161  static void kqemu_update_cpuid(CPUState 
   
 int kqemu_init(CPUState *env)  int kqemu_init(CPUState *env)
 {  {
     struct kqemu_init init;      struct kqemu_init kinit;
     int ret, version;      int ret, version;
 #ifdef _WIN32  #ifdef _WIN32
     DWORD temp;      DWORD temp;
Line 174  int kqemu_init(CPUState *env) Line 175  int kqemu_init(CPUState *env)
                           FILE_SHARE_READ | FILE_SHARE_WRITE,                            FILE_SHARE_READ | FILE_SHARE_WRITE,
                           NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,                            NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                           NULL);                            NULL);
       if (kqemu_fd == KQEMU_INVALID_FD) {
           fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",
                   KQEMU_DEVICE, GetLastError());
           return -1;
       }
 #else  #else
     kqemu_fd = open(KQEMU_DEVICE, O_RDWR);      kqemu_fd = open(KQEMU_DEVICE, O_RDWR);
 #endif  
     if (kqemu_fd == KQEMU_INVALID_FD) {      if (kqemu_fd == KQEMU_INVALID_FD) {
         fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",          fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",
                 KQEMU_DEVICE, strerror(errno));                  KQEMU_DEVICE, strerror(errno));
         return -1;          return -1;
     }      }
   #endif
     version = 0;      version = 0;
 #ifdef _WIN32  #ifdef _WIN32
     DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,      DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,
Line 196  int kqemu_init(CPUState *env) Line 202  int kqemu_init(CPUState *env)
     }      }
   
     pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *      pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *
                                   sizeof(unsigned long));                                    sizeof(uint64_t));
     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(uint64_t));
     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(uint64_t));
     if (!modified_ram_pages)      if (!modified_ram_pages)
         goto fail;          goto fail;
     modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS);      modified_ram_pages_table = qemu_mallocz(phys_ram_size >> TARGET_PAGE_BITS);
     if (!modified_ram_pages_table)      if (!modified_ram_pages_table)
         goto fail;          goto fail;
   
     init.ram_base = phys_ram_base;      memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */
     init.ram_size = phys_ram_size;      kinit.ram_base = phys_ram_base;
     init.ram_dirty = phys_ram_dirty;      kinit.ram_size = phys_ram_size;
     init.phys_to_ram_map = l1_phys_map;      kinit.ram_dirty = phys_ram_dirty;
     init.pages_to_flush = pages_to_flush;      kinit.pages_to_flush = pages_to_flush;
 #if KQEMU_VERSION >= 0x010200      kinit.ram_pages_to_update = ram_pages_to_update;
     init.ram_pages_to_update = ram_pages_to_update;      kinit.modified_ram_pages = modified_ram_pages;
 #endif  
 #if KQEMU_VERSION >= 0x010300  
     init.modified_ram_pages = modified_ram_pages;  
 #endif  
 #ifdef _WIN32  #ifdef _WIN32
     ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &init, sizeof(init),      ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &kinit, sizeof(kinit),
                           NULL, 0, &temp, NULL) == TRUE ? 0 : -1;                            NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
 #else  #else
     ret = ioctl(kqemu_fd, KQEMU_INIT, &init);      ret = ioctl(kqemu_fd, KQEMU_INIT, &kinit);
 #endif  #endif
     if (ret < 0) {      if (ret < 0) {
         fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);          fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);
Line 241  int kqemu_init(CPUState *env) Line 243  int kqemu_init(CPUState *env)
     env->kqemu_enabled = kqemu_allowed;      env->kqemu_enabled = kqemu_allowed;
     nb_pages_to_flush = 0;      nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;      nb_ram_pages_to_update = 0;
   
       qpi_init();
     return 0;      return 0;
 }  }
   
 void kqemu_flush_page(CPUState *env, target_ulong addr)  void kqemu_flush_page(CPUState *env, target_ulong addr)
 {  {
 #if defined(DEBUG)      LOG_INT("kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);
     if (loglevel & CPU_LOG_INT) {  
         fprintf(logfile, "kqemu_flush_page: addr=" TARGET_FMT_lx "\n", addr);  
     }  
 #endif  
     if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)      if (nb_pages_to_flush >= KQEMU_MAX_PAGES_TO_FLUSH)
         nb_pages_to_flush = KQEMU_FLUSH_ALL;          nb_pages_to_flush = KQEMU_FLUSH_ALL;
     else      else
Line 259  void kqemu_flush_page(CPUState *env, tar Line 259  void kqemu_flush_page(CPUState *env, tar
   
 void kqemu_flush(CPUState *env, int global)  void kqemu_flush(CPUState *env, int global)
 {  {
 #ifdef DEBUG      LOG_INT("kqemu_flush:\n");
     if (loglevel & CPU_LOG_INT) {  
         fprintf(logfile, "kqemu_flush:\n");  
     }  
 #endif  
     nb_pages_to_flush = KQEMU_FLUSH_ALL;      nb_pages_to_flush = KQEMU_FLUSH_ALL;
 }  }
   
 void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)  void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
 {  {
 #ifdef DEBUG      LOG_INT("kqemu_set_notdirty: addr=%08lx\n", 
     if (loglevel & CPU_LOG_INT) {                  (unsigned long)ram_addr);
         fprintf(logfile, "kqemu_set_notdirty: addr=%08lx\n", ram_addr);  
     }  
 #endif  
     /* we only track transitions to dirty state */      /* we only track transitions to dirty state */
     if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)      if (phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] != 0xff)
         return;          return;
Line 326  void kqemu_modify_page(CPUState *env, ra Line 319  void kqemu_modify_page(CPUState *env, ra
     }      }
 }  }
   
   void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
                           ram_addr_t phys_offset)
   {
       struct kqemu_phys_mem kphys_mem1, *kphys_mem = &kphys_mem1;
       uint64_t end;
       int ret, io_index;
   
       end = (start_addr + size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
       start_addr &= TARGET_PAGE_MASK;
       kphys_mem->phys_addr = start_addr;
       kphys_mem->size = end - start_addr;
       kphys_mem->ram_addr = phys_offset & TARGET_PAGE_MASK;
       io_index = phys_offset & ~TARGET_PAGE_MASK;
       switch(io_index) {
       case IO_MEM_RAM:
           kphys_mem->io_index = KQEMU_IO_MEM_RAM;
           break;
       case IO_MEM_ROM:
           kphys_mem->io_index = KQEMU_IO_MEM_ROM;
           break;
       default:
           if (qpi_io_memory == io_index) {
               kphys_mem->io_index = KQEMU_IO_MEM_COMM;
           } else {
               kphys_mem->io_index = KQEMU_IO_MEM_UNASSIGNED;
           }
           break;
       }
   #ifdef _WIN32
       {
           DWORD temp;
           ret = DeviceIoControl(kqemu_fd, KQEMU_SET_PHYS_MEM, 
                                 kphys_mem, sizeof(*kphys_mem),
                                 NULL, 0, &temp, NULL) == TRUE ? 0 : -1;
       }
   #else
       ret = ioctl(kqemu_fd, KQEMU_SET_PHYS_MEM, kphys_mem);
   #endif
       if (ret < 0) {
           fprintf(stderr, "kqemu: KQEMU_SET_PHYS_PAGE error=%d: start_addr=0x%016" PRIx64 " size=0x%08lx phys_offset=0x%08lx\n",
                   ret, start_addr, 
                   (unsigned long)size, (unsigned long)phys_offset);
       }
   }
   
 struct fpstate {  struct fpstate {
     uint16_t fpuc;      uint16_t fpuc;
     uint16_t dummy1;      uint16_t dummy1;
Line 473  static int do_syscall(CPUState *env, Line 511  static int do_syscall(CPUState *env,
     int selector;      int selector;
   
     selector = (env->star >> 32) & 0xffff;      selector = (env->star >> 32) & 0xffff;
 #ifdef __x86_64__  #ifdef TARGET_X86_64
     if (env->hflags & HF_LMA_MASK) {      if (env->hflags & HF_LMA_MASK) {
         int code64;          int code64;
   
Line 630  void kqemu_record_dump(void) Line 668  void kqemu_record_dump(void)
 }  }
 #endif  #endif
   
   static inline void kqemu_load_seg(struct kqemu_segment_cache *ksc,
                                     const SegmentCache *sc)
   {
       ksc->selector = sc->selector;
       ksc->flags = sc->flags;
       ksc->limit = sc->limit;
       ksc->base = sc->base;
   }
   
   static inline void kqemu_save_seg(SegmentCache *sc,
                                     const struct kqemu_segment_cache *ksc)
   {
       sc->selector = ksc->selector;
       sc->flags = ksc->flags;
       sc->limit = ksc->limit;
       sc->base = ksc->base;
   }
   
 int kqemu_cpu_exec(CPUState *env)  int kqemu_cpu_exec(CPUState *env)
 {  {
     struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;      struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
Line 637  int kqemu_cpu_exec(CPUState *env) Line 693  int kqemu_cpu_exec(CPUState *env)
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
     int64_t ti;      int64_t ti;
 #endif  #endif
   
 #ifdef _WIN32  #ifdef _WIN32
     DWORD temp;      DWORD temp;
 #endif  #endif
Line 645  int kqemu_cpu_exec(CPUState *env) Line 700  int kqemu_cpu_exec(CPUState *env)
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
     ti = profile_getclock();      ti = profile_getclock();
 #endif  #endif
 #ifdef DEBUG      LOG_INT("kqemu: cpu_exec: enter\n");
     if (loglevel & CPU_LOG_INT) {      LOG_INT_STATE(env);
         fprintf(logfile, "kqemu: cpu_exec: enter\n");      for(i = 0; i < CPU_NB_REGS; i++)
         cpu_dump_state(env, logfile, fprintf, 0);          kenv->regs[i] = env->regs[i];
     }  
 #endif  
     memcpy(kenv->regs, env->regs, sizeof(kenv->regs));  
     kenv->eip = env->eip;      kenv->eip = env->eip;
     kenv->eflags = env->eflags;      kenv->eflags = env->eflags;
     memcpy(&kenv->segs, &env->segs, sizeof(env->segs));      for(i = 0; i < 6; i++)
     memcpy(&kenv->ldt, &env->ldt, sizeof(env->ldt));          kqemu_load_seg(&kenv->segs[i], &env->segs[i]);
     memcpy(&kenv->tr, &env->tr, sizeof(env->tr));      kqemu_load_seg(&kenv->ldt, &env->ldt);
     memcpy(&kenv->gdt, &env->gdt, sizeof(env->gdt));      kqemu_load_seg(&kenv->tr, &env->tr);
     memcpy(&kenv->idt, &env->idt, sizeof(env->idt));      kqemu_load_seg(&kenv->gdt, &env->gdt);
       kqemu_load_seg(&kenv->idt, &env->idt);
     kenv->cr0 = env->cr[0];      kenv->cr0 = env->cr[0];
     kenv->cr2 = env->cr[2];      kenv->cr2 = env->cr[2];
     kenv->cr3 = env->cr[3];      kenv->cr3 = env->cr[3];
     kenv->cr4 = env->cr[4];      kenv->cr4 = env->cr[4];
     kenv->a20_mask = env->a20_mask;      kenv->a20_mask = env->a20_mask;
 #if KQEMU_VERSION >= 0x010100  
     kenv->efer = env->efer;      kenv->efer = env->efer;
 #endif  
 #if KQEMU_VERSION >= 0x010300  
     kenv->tsc_offset = 0;      kenv->tsc_offset = 0;
     kenv->star = env->star;      kenv->star = env->star;
     kenv->sysenter_cs = env->sysenter_cs;      kenv->sysenter_cs = env->sysenter_cs;
     kenv->sysenter_esp = env->sysenter_esp;      kenv->sysenter_esp = env->sysenter_esp;
     kenv->sysenter_eip = env->sysenter_eip;      kenv->sysenter_eip = env->sysenter_eip;
 #ifdef __x86_64__  #ifdef TARGET_X86_64
     kenv->lstar = env->lstar;      kenv->lstar = env->lstar;
     kenv->cstar = env->cstar;      kenv->cstar = env->cstar;
     kenv->fmask = env->fmask;      kenv->fmask = env->fmask;
     kenv->kernelgsbase = env->kernelgsbase;      kenv->kernelgsbase = env->kernelgsbase;
 #endif  #endif
 #endif  
     if (env->dr[7] & 0xff) {      if (env->dr[7] & 0xff) {
         kenv->dr7 = env->dr[7];          kenv->dr7 = env->dr[7];
         kenv->dr0 = env->dr[0];          kenv->dr0 = env->dr[0];
Line 693  int kqemu_cpu_exec(CPUState *env) Line 742  int kqemu_cpu_exec(CPUState *env)
     cpl = (env->hflags & HF_CPL_MASK);      cpl = (env->hflags & HF_CPL_MASK);
     kenv->cpl = cpl;      kenv->cpl = cpl;
     kenv->nb_pages_to_flush = nb_pages_to_flush;      kenv->nb_pages_to_flush = nb_pages_to_flush;
 #if KQEMU_VERSION >= 0x010200  
     kenv->user_only = (env->kqemu_enabled == 1);      kenv->user_only = (env->kqemu_enabled == 1);
     kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;      kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
 #endif  
     nb_ram_pages_to_update = 0;      nb_ram_pages_to_update = 0;
   
 #if KQEMU_VERSION >= 0x010300  
     kenv->nb_modified_ram_pages = nb_modified_ram_pages;      kenv->nb_modified_ram_pages = nb_modified_ram_pages;
 #endif  
     kqemu_reset_modified_ram_pages();      kqemu_reset_modified_ram_pages();
   
     if (env->cpuid_features & CPUID_FXSR)      if (env->cpuid_features & CPUID_FXSR)
Line 719  int kqemu_cpu_exec(CPUState *env) Line 764  int kqemu_cpu_exec(CPUState *env)
         ret = -1;          ret = -1;
     }      }
 #else  #else
 #if KQEMU_VERSION >= 0x010100  
     ioctl(kqemu_fd, KQEMU_EXEC, kenv);      ioctl(kqemu_fd, KQEMU_EXEC, kenv);
     ret = kenv->retval;      ret = kenv->retval;
 #else  
     ret = ioctl(kqemu_fd, KQEMU_EXEC, kenv);  
 #endif  
 #endif  #endif
     if (env->cpuid_features & CPUID_FXSR)      if (env->cpuid_features & CPUID_FXSR)
         save_native_fp_fxsave(env);          save_native_fp_fxsave(env);
     else      else
         save_native_fp_fsave(env);          save_native_fp_fsave(env);
   
     memcpy(env->regs, kenv->regs, sizeof(env->regs));      for(i = 0; i < CPU_NB_REGS; i++)
           env->regs[i] = kenv->regs[i];
     env->eip = kenv->eip;      env->eip = kenv->eip;
     env->eflags = kenv->eflags;      env->eflags = kenv->eflags;
     memcpy(env->segs, kenv->segs, sizeof(env->segs));      for(i = 0; i < 6; i++)
           kqemu_save_seg(&env->segs[i], &kenv->segs[i]);
     cpu_x86_set_cpl(env, kenv->cpl);      cpu_x86_set_cpl(env, kenv->cpl);
     memcpy(&env->ldt, &kenv->ldt, sizeof(env->ldt));      kqemu_save_seg(&env->ldt, &kenv->ldt);
 #if 0  
     /* no need to restore that */  
     memcpy(env->tr, kenv->tr, sizeof(env->tr));  
     memcpy(env->gdt, kenv->gdt, sizeof(env->gdt));  
     memcpy(env->idt, kenv->idt, sizeof(env->idt));  
     env->a20_mask = kenv->a20_mask;  
 #endif  
     env->cr[0] = kenv->cr0;      env->cr[0] = kenv->cr0;
     env->cr[4] = kenv->cr4;      env->cr[4] = kenv->cr4;
     env->cr[3] = kenv->cr3;      env->cr[3] = kenv->cr3;
     env->cr[2] = kenv->cr2;      env->cr[2] = kenv->cr2;
     env->dr[6] = kenv->dr6;      env->dr[6] = kenv->dr6;
 #if KQEMU_VERSION >= 0x010300  #ifdef TARGET_X86_64
 #ifdef __x86_64__  
     env->kernelgsbase = kenv->kernelgsbase;      env->kernelgsbase = kenv->kernelgsbase;
 #endif  #endif
 #endif  
   
     /* flush pages as indicated by kqemu */      /* flush pages as indicated by kqemu */
     if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) {      if (kenv->nb_pages_to_flush >= KQEMU_FLUSH_ALL) {
Line 770  int kqemu_cpu_exec(CPUState *env) Line 804  int kqemu_cpu_exec(CPUState *env)
     kqemu_exec_count++;      kqemu_exec_count++;
 #endif  #endif
   
 #if KQEMU_VERSION >= 0x010200  
     if (kenv->nb_ram_pages_to_update > 0) {      if (kenv->nb_ram_pages_to_update > 0) {
         cpu_tlb_update_dirty(env);          cpu_tlb_update_dirty(env);
     }      }
 #endif  
   
 #if KQEMU_VERSION >= 0x010300  
     if (kenv->nb_modified_ram_pages > 0) {      if (kenv->nb_modified_ram_pages > 0) {
         for(i = 0; i < kenv->nb_modified_ram_pages; i++) {          for(i = 0; i < kenv->nb_modified_ram_pages; i++) {
             unsigned long addr;              unsigned long addr;
Line 784  int kqemu_cpu_exec(CPUState *env) Line 815  int kqemu_cpu_exec(CPUState *env)
             tb_invalidate_phys_page_range(addr, addr + TARGET_PAGE_SIZE, 0);              tb_invalidate_phys_page_range(addr, addr + TARGET_PAGE_SIZE, 0);
         }          }
     }      }
 #endif  
   
     /* restore the hidden flags */      /* restore the hidden flags */
     {      {
Line 830  int kqemu_cpu_exec(CPUState *env) Line 860  int kqemu_cpu_exec(CPUState *env)
     else      else
         env->hflags &= ~HF_OSFXSR_MASK;          env->hflags &= ~HF_OSFXSR_MASK;
   
 #ifdef DEBUG      LOG_INT("kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);
     if (loglevel & CPU_LOG_INT) {  
         fprintf(logfile, "kqemu: kqemu_cpu_exec: ret=0x%x\n", ret);  
     }  
 #endif  
     if (ret == KQEMU_RET_SYSCALL) {      if (ret == KQEMU_RET_SYSCALL) {
         /* syscall instruction */          /* syscall instruction */
         return do_syscall(env, kenv);          return do_syscall(env, kenv);
Line 847  int kqemu_cpu_exec(CPUState *env) Line 873  int kqemu_cpu_exec(CPUState *env)
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
         kqemu_ret_int_count++;          kqemu_ret_int_count++;
 #endif  #endif
 #ifdef DEBUG          LOG_INT("kqemu: interrupt v=%02x:\n", env->exception_index);
         if (loglevel & CPU_LOG_INT) {          LOG_INT_STATE(env);
             fprintf(logfile, "kqemu: interrupt v=%02x:\n",  
                     env->exception_index);  
             cpu_dump_state(env, logfile, fprintf, 0);  
         }  
 #endif  
         return 1;          return 1;
     } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {      } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
         env->exception_index = ret & 0xff;          env->exception_index = ret & 0xff;
Line 863  int kqemu_cpu_exec(CPUState *env) Line 884  int kqemu_cpu_exec(CPUState *env)
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
         kqemu_ret_excp_count++;          kqemu_ret_excp_count++;
 #endif  #endif
 #ifdef DEBUG          LOG_INT("kqemu: exception v=%02x e=%04x:\n",
         if (loglevel & CPU_LOG_INT) {  
             fprintf(logfile, "kqemu: exception v=%02x e=%04x:\n",  
                     env->exception_index, env->error_code);                      env->exception_index, env->error_code);
             cpu_dump_state(env, logfile, fprintf, 0);          LOG_INT_STATE(env);
         }  
 #endif  
         return 1;          return 1;
     } else if (ret == KQEMU_RET_INTR) {      } else if (ret == KQEMU_RET_INTR) {
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
         kqemu_ret_intr_count++;          kqemu_ret_intr_count++;
 #endif  #endif
 #ifdef DEBUG          LOG_INT_STATE(env);
         if (loglevel & CPU_LOG_INT) {  
             cpu_dump_state(env, logfile, fprintf, 0);  
         }  
 #endif  
         return 0;          return 0;
     } else if (ret == KQEMU_RET_SOFTMMU) {      } else if (ret == KQEMU_RET_SOFTMMU) {
 #ifdef CONFIG_PROFILER  #ifdef CONFIG_PROFILER
Line 888  int kqemu_cpu_exec(CPUState *env) Line 901  int kqemu_cpu_exec(CPUState *env)
             kqemu_record_pc(pc);              kqemu_record_pc(pc);
         }          }
 #endif  #endif
 #ifdef DEBUG          LOG_INT_STATE(env);
         if (loglevel & CPU_LOG_INT) {  
             cpu_dump_state(env, logfile, fprintf, 0);  
         }  
 #endif  
         return 2;          return 2;
     } else {      } else {
         cpu_dump_state(env, stderr, fprintf, 0);          cpu_dump_state(env, stderr, fprintf, 0);
Line 904  int kqemu_cpu_exec(CPUState *env) Line 913  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)
     /* 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
 }  }
   
   /* 
      QEMU paravirtualization interface. The current interface only
      allows to modify the IF and IOPL flags when running in
      kqemu.
   
      At this point it is not very satisfactory. I leave it for reference
      as it adds little complexity.
   */
   
   #define QPI_COMM_PAGE_PHYS_ADDR 0xff000000
   
   static uint32_t qpi_mem_readb(void *opaque, target_phys_addr_t addr)
   {
       return 0;
   }
   
   static uint32_t qpi_mem_readw(void *opaque, target_phys_addr_t addr)
   {
       return 0;
   }
   
   static void qpi_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
   {
   }
   
   static void qpi_mem_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
   {
   }
   
   static uint32_t qpi_mem_readl(void *opaque, target_phys_addr_t addr)
   {
       CPUState *env;
   
       env = cpu_single_env;
       if (!env)
           return 0;
       return env->eflags & (IF_MASK | IOPL_MASK);
   }
   
   /* Note: after writing to this address, the guest code must make sure
      it is exiting the current TB. pushf/popf can be used for that
      purpose. */
   static void qpi_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
   {
       CPUState *env;
   
       env = cpu_single_env;
       if (!env)
           return;
       env->eflags = (env->eflags & ~(IF_MASK | IOPL_MASK)) | 
           (val & (IF_MASK | IOPL_MASK));
   }
   
   static CPUReadMemoryFunc *qpi_mem_read[3] = {
       qpi_mem_readb,
       qpi_mem_readw,
       qpi_mem_readl,
   };
   
   static CPUWriteMemoryFunc *qpi_mem_write[3] = {
       qpi_mem_writeb,
       qpi_mem_writew,
       qpi_mem_writel,
   };
   
   static void qpi_init(void)
   {
       kqemu_comm_base = 0xff000000 | 1;
       qpi_io_memory = cpu_register_io_memory(0, 
                                              qpi_mem_read, 
                                              qpi_mem_write, NULL);
       cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
                                    0x1000, qpi_io_memory);
   }
 #endif  #endif

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


unix.superglobalmegacorp.com