qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Re: [PATCH 27/32] arch-specific hooks for accelerator
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator Glauber Costa
@ 2008-10-23 13:30   ` Avi Kivity
  2008-10-23 13:35     ` Jan Kiszka
  0 siblings, 1 reply; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 13:30 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, aliguori, jes, qemu-devel, dmitry.baryshkov

Glauber Costa wrote:
> This patch provides an arch field in QEMUAccel. It will
> be used initially for x86, to replace kqemu code in op_helper.c
> We start with get_msr and set_msr functions, that allow accelerators
> to handle non-default msrs.
>
> @@ -23,6 +23,7 @@ typedef struct QEMUAccel {
>      void (*trace_io)(CPUState *env);
>      int (*break_loop)(CPUState *env);
>      int (*cpu_exec)(CPUState *env);
> +    void *arch; /* arch-specific accel functions */
>  } QEMUAccel

This is more elegant IMO using container_of() and including the common 
part as a member.  Less pointers to chase.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 27/32] arch-specific hooks for accelerator
  2008-10-23 13:30   ` [Qemu-devel] " Avi Kivity
@ 2008-10-23 13:35     ` Jan Kiszka
  2008-10-23 13:47       ` Avi Kivity
  0 siblings, 1 reply; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 13:35 UTC (permalink / raw)
  To: Avi Kivity; +Cc: aliguori, Glauber Costa, jes, qemu-devel, dmitry.baryshkov

Avi Kivity wrote:
> Glauber Costa wrote:
>> This patch provides an arch field in QEMUAccel. It will
>> be used initially for x86, to replace kqemu code in op_helper.c
>> We start with get_msr and set_msr functions, that allow accelerators
>> to handle non-default msrs.
>>
>> @@ -23,6 +23,7 @@ typedef struct QEMUAccel {
>>      void (*trace_io)(CPUState *env);
>>      int (*break_loop)(CPUState *env);
>>      int (*cpu_exec)(CPUState *env);
>> +    void *arch; /* arch-specific accel functions */
>>  } QEMUAccel
> 
> This is more elegant IMO using container_of() and including the common
> part as a member.  Less pointers to chase.

...or to have some kind of QEMUAccel_arch, defined in target-*/accel.h
files. Haven't looked into the use cases yet to say what is sufficient.

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 0/32] New shot at accelerators
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
@ 2008-10-23 13:35 ` Jan Kiszka
  2008-10-23 14:07   ` Glauber Costa
  2008-10-23 13:44 ` Anthony Liguori
                   ` (32 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 13:35 UTC (permalink / raw)
  To: Glauber Costa; +Cc: aliguori, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> Hi guys,
>  
> I'm sending here a new version of the accel patch. It comprises
> the cleaned up version I've last sent, plus a few additions
> 
> You may want to pay special attention to the additions, since
> they are newcomers to the series. To ease your job, they are:
> 
> 0001-use-anonymous-memory-for-kqemu.patch
> 0002-protect-exec-all.h-frm-multiple-inclusion.patch
> 0003-change-definition-of-FILE-for-linux.patch
> 0005-use-more-meaningful-values-for-kqemu_cpu_exec.patch
> 0025-provide-accel-hook-for-cpu_exec.patch
> 0026-provide-two-accelerators-for-kqemu.patch
> 0027-arch-specific-hooks-for-accelerator.patch
> 0028-iret-arch-specific-accelerator.patch
> 0029-sysret-sysexit-arch-specific-accelerator.patch
> 0030-lcall-lret-arch-specific-accel-hooks.patch
> 0031-remove-kqemu_is_ok-tests.patch
> 0032-clean-up-kqemu-code.patch
> 
> git users can get a snapshot of it located at
> 
> git://git.kernel.org/pub/scm/virt/glommer/qemu-accel.git accel-v2
> 
> diffstat and OBP (One Big Patch ;-)) attached.
> 

Careful question: Build-tested against other OSes beyond /The OS/ ;)?

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
@ 2008-10-23 13:35   ` Jan Kiszka
  2008-10-23 13:48   ` Anthony Liguori
  1 sibling, 0 replies; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 13:35 UTC (permalink / raw)
  To: Glauber Costa; +Cc: aliguori, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> Signed-off-by: Glauber Costa <glommer@redhat.com>

-ENOREASON

What was the original idea behind using a named mem region? Why is it no
longer needed? Maybe I missed that point on the list, but then it would
still be nice-to-have in the changelog.

> ---
>  osdep.c |  111 ---------------------------------------------------------------
>  1 files changed, 0 insertions(+), 111 deletions(-)
> 
> diff --git a/osdep.c b/osdep.c
> index 683aad0..31c96e6 100644
> --- a/osdep.c
> +++ b/osdep.c
> @@ -68,112 +68,9 @@ void qemu_vfree(void *ptr)
>  
>  #else
>  
> -#if defined(USE_KQEMU)
> -
> -#ifdef __OpenBSD__
> -#include <sys/param.h>
> -#include <sys/types.h>
> -#include <sys/mount.h>
> -#else
> -#include <sys/vfs.h>
> -#endif
> -
>  #include <sys/mman.h>
>  #include <fcntl.h>
>  
> -static void *kqemu_vmalloc(size_t size)
> -{
> -    static int phys_ram_fd = -1;
> -    static int phys_ram_size = 0;
> -    void *ptr;
> -
> -#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
> -    int map_anon = MAP_ANON;
> -#else
> -    int map_anon = 0;
> -    const char *tmpdir;
> -    char phys_ram_file[1024];
> -#ifdef HOST_SOLARIS
> -    struct statvfs stfs;
> -#else
> -    struct statfs stfs;
> -#endif
> -
> -    if (phys_ram_fd < 0) {
> -        tmpdir = getenv("QEMU_TMPDIR");
> -        if (!tmpdir)
> -#ifdef HOST_SOLARIS
> -            tmpdir = "/tmp";
> -        if (statvfs(tmpdir, &stfs) == 0) {
> -#else
> -            tmpdir = "/dev/shm";
> -        if (statfs(tmpdir, &stfs) == 0) {
> -#endif
> -            int64_t free_space;
> -            int ram_mb;
> -
> -            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
> -            if ((ram_size + 8192 * 1024) >= free_space) {
> -                ram_mb = (ram_size / (1024 * 1024));
> -                fprintf(stderr,
> -                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
> -                        tmpdir, ram_mb);
> -                if (strcmp(tmpdir, "/dev/shm") == 0) {
> -                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
> -                            "mount -o remount,size=%dm /dev/shm\n",
> -                            ram_mb + 16);
> -                } else {
> -                    fprintf(stderr,
> -                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
> -                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
> -                            "temporary RAM file will be opened.\n");
> -                }
> -                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
> -                exit(1);
> -            }
> -        }
> -        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
> -                 tmpdir);
> -        phys_ram_fd = mkstemp(phys_ram_file);
> -        if (phys_ram_fd < 0) {
> -            fprintf(stderr,
> -                    "warning: could not create temporary file in '%s'.\n"
> -                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
> -                    "Using '/tmp' as fallback.\n",
> -                    tmpdir);
> -            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
> -                     "/tmp");
> -            phys_ram_fd = mkstemp(phys_ram_file);
> -            if (phys_ram_fd < 0) {
> -                fprintf(stderr, "Could not create temporary memory file '%s'\n",
> -                        phys_ram_file);
> -                exit(1);
> -            }
> -        }
> -        unlink(phys_ram_file);
> -    }
> -    size = (size + 4095) & ~4095;
> -    ftruncate(phys_ram_fd, phys_ram_size + size);
> -#endif /* !__OpenBSD__ */
> -    ptr = mmap(NULL,
> -               size,
> -               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
> -               phys_ram_fd, phys_ram_size);
> -    if (ptr == MAP_FAILED) {
> -        fprintf(stderr, "Could not map physical memory\n");
> -        exit(1);
> -    }
> -    phys_ram_size += size;
> -    return ptr;
> -}
> -
> -static void kqemu_vfree(void *ptr)
> -{
> -    /* may be useful some day, but currently we do not need to free */
> -}
> -
> -#endif
> -
>  void *qemu_memalign(size_t alignment, size_t size)
>  {
>  #if defined(_POSIX_C_SOURCE)
> @@ -193,10 +90,6 @@ void *qemu_memalign(size_t alignment, size_t size)
>  /* alloc shared memory pages */
>  void *qemu_vmalloc(size_t size)
>  {
> -#if defined(USE_KQEMU)
> -    if (kqemu_allowed)
> -        return kqemu_vmalloc(size);
> -#endif
>  #ifdef _BSD
>      return valloc(size);
>  #else
> @@ -206,10 +99,6 @@ void *qemu_vmalloc(size_t size)
>  
>  void qemu_vfree(void *ptr)
>  {
> -#if defined(USE_KQEMU)
> -    if (kqemu_allowed)
> -        kqemu_vfree(ptr);
> -#endif
>      free(ptr);
>  }
>  

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 21/32] get_env accel wrapper
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 21/32] get_env accel wrapper Glauber Costa
@ 2008-10-23 13:36   ` Avi Kivity
  0 siblings, 0 replies; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 13:36 UTC (permalink / raw)
  To: Glauber Costa
  Cc: aliguori, jan.kiszka, jes, qemu-devel, Glauber Costa,
	dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> Allow the current accelerator to provide it's own, customized
> address of the CPUState structure used for the env variable.
>  
>  /* Accelerator wrapper for the no-accel (raw qemu) case */
> @@ -21,6 +26,7 @@ QEMUAccel noaccel = {
>      .name = "none",
>      .cpu_interrupt = accel_nop,
>      .init_env = accel_nop,
> +    .get_env = noaccel_get_env,
>   

.create_env() ?

>  
> +typedef struct KQEMUCPUstate {
> +    int kqemu_enabled;
> +    int last_io_time;
> +    CPUState env;
>   

Tradition is to put it as the first member.

> +} KQEMUCPUState;
> +
> +#define kqemu_cpu_field(env, field) (*({ \
> +    KQEMUCPUState *__c = container_of(env, KQEMUCPUState, env); \
> +    &__c->field; }))
>   

This is evil.  The resulting code is less readable.

I'd prefer a KQEMUCPUState *kqemu_state(CPUState *env) { ... } even 
though it means one more line of code per usage.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 24/32] check wether kqemu is enabled in open code
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
@ 2008-10-23 13:38   ` Jan Kiszka
  2008-10-23 14:49     ` Glauber Costa
  2008-10-23 14:23   ` Anthony Liguori
  1 sibling, 1 reply; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 13:38 UTC (permalink / raw)
  To: Glauber Costa; +Cc: aliguori, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> kqemu is still too much spread around. The proper fix
> usually involves rethinking a bit of kqemu logic so for now,
> just check whether or not kqemu is enabled. If the kqemu accelerator
> is not present, consider it not. Otherwise, check env field.
> 
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  cpu-exec.c |    2 +-
>  kqemu.c    |   21 +++++++++++++++++++++
>  kqemu.h    |    3 +++
>  3 files changed, 25 insertions(+), 1 deletions(-)
> 
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 18908d5..b47cf43 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
>                  {
>                      if (next_tb != 0 &&
>  #ifdef USE_KQEMU
> -                        (env->kqemu_enabled != 2) &&
> +                        (!kqemu_kernel_enabled(env)) &&
>  #endif

If this ifdef is still here to foster rethinking of the check - OK :).
Otherwise I would suggest to wrap kqemu_kernel_enabled for the
!USE_KQEMU case.

>                          tb->page_addr[1] == -1) {
>                      tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
> diff --git a/kqemu.c b/kqemu.c
> index 16ebe7d..f99a4f1 100644
> --- a/kqemu.c
> +++ b/kqemu.c
> @@ -126,6 +126,27 @@ static int is_cpuid_supported(void)
>  }
>  #endif
>  
> +/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
> + * altogether
> + */
> +int kqemu_is_enabled(CPUState *env)
> +{
> +    if (strcasecmp(current_accel->name, "kqemu")) {
> +        return 0;
> +    }
> +
> +    return env->kqemu_enabled;
> +
> +}
> +
> +int kqemu_kernel_enabled(CPUState *env)
> +{
> +    if (strcasecmp(current_accel->name, "kqemu")) {
> +        return 0;
> +    }
> +    return env->kqemu_enabled == 2;
> +}
> +
>  static void kqemu_update_cpuid(CPUState *env)
>  {
>      int critical_features_mask, features, ext_features, ext_features_mask;
> diff --git a/kqemu.h b/kqemu.h
> index cf14179..62ba1d9 100644
> --- a/kqemu.h
> +++ b/kqemu.h
> @@ -157,6 +157,9 @@ struct kqemu_phys_mem {
>  #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
>  #endif
>  
> +int kqemu_is_enabled(CPUState *env);
> +int kqemu_kernel_enabled(CPUState *env);
> +
>  typedef struct KQEMUCPUstate {
>      int kqemu_enabled;
>      int last_io_time;

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 0/32] New shot at accelerators
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
  2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
@ 2008-10-23 13:44 ` Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
                   ` (31 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:44 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> Hi guys,
>
> I'm sending here a new version of the accel patch. It comprises
> the cleaned up version I've last sent, plus a few additions
>
> You may want to pay special attention to the additions, since
> they are newcomers to the series. To ease your job, they are:
>
> 0001-use-anonymous-memory-for-kqemu.patch
> 0002-protect-exec-all.h-frm-multiple-inclusion.patch
> 0003-change-definition-of-FILE-for-linux.patch
> 0005-use-more-meaningful-values-for-kqemu_cpu_exec.patch
> 0025-provide-accel-hook-for-cpu_exec.patch
> 0026-provide-two-accelerators-for-kqemu.patch
> 0027-arch-specific-hooks-for-accelerator.patch
> 0028-iret-arch-specific-accelerator.patch
> 0029-sysret-sysexit-arch-specific-accelerator.patch
> 0030-lcall-lret-arch-specific-accel-hooks.patch
> 0031-remove-kqemu_is_ok-tests.patch
> 0032-clean-up-kqemu-code.patch
>
> git users can get a snapshot of it located at
>
> git://git.kernel.org/pub/scm/virt/glommer/qemu-accel.git accel-v2
>
> diffstat and OBP (One Big Patch ;-)) attached.
>   

So in general, the patches need better descriptions.  Also, some of this 
is going to need Fabrice's ack.  I'll try to be specific for those in 
follow-up notes.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 17/32] build list of available accelerators
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 17/32] build list of available accelerators Glauber Costa
@ 2008-10-23 13:45   ` Avi Kivity
  2008-10-23 15:09     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 13:45 UTC (permalink / raw)
  To: Glauber Costa
  Cc: aliguori, jan.kiszka, jes, qemu-devel, Glauber Costa,
	dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> instead of hardcoding kqemu_start() in exec.c, which would require
> such a hack for all available accelerators, semantics of register_qemu_accel()
> is changed a little bit. It only builds a list of available accelerators.
> The last one registered is the first tried.
>
> This is a temporary solution, since we don't control exactly the order in which
> things are loaded by the constructor attributes. The final goal is to have command
> line switches and priority lists to determine that.
>
> "info accelerator" is changed to accomodate it. It now prints a list of available
> accelerators, and only if one of them is active, a detailed description of it is printed.
>
>  #define MAX_INFO_BUF 1024
>  
>  typedef struct QEMUAccel {
> +    char *name;
>   

const, or warnings you get.

>  
> +typedef struct QEMUCont {
> +    QEMUAccel *acc;
> +    int active;
> +    struct QEMUCont *next;
> +} QEMUCont;
>   

The name is unclear.  But you could fold the structure into QEMUAccel, no?

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 27/32] arch-specific hooks for accelerator
  2008-10-23 13:35     ` Jan Kiszka
@ 2008-10-23 13:47       ` Avi Kivity
  0 siblings, 0 replies; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 13:47 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: aliguori, Glauber Costa, jes, qemu-devel, dmitry.baryshkov

Jan Kiszka wrote:
>>>      void (*trace_io)(CPUState *env);
>>>      int (*break_loop)(CPUState *env);
>>>      int (*cpu_exec)(CPUState *env);
>>> +    void *arch; /* arch-specific accel functions */
>>>  } QEMUAccel
>>>       
>> This is more elegant IMO using container_of() and including the common
>> part as a member.  Less pointers to chase.
>>     
>
> ...or to have some kind of QEMUAccel_arch, defined in target-*/accel.h
> files. Haven't looked into the use cases yet to say what is sufficient.
>   

You're right, there's no need for run-time dynamic types here.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
  2008-10-23 13:35   ` [Qemu-devel] " Jan Kiszka
@ 2008-10-23 13:48   ` Anthony Liguori
  2008-10-23 14:17     ` Jan Kiszka
  1 sibling, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:48 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

The idea behind this patch is that currently kqemu uses /dev/shm for 
memory allocations instead of anonymous memory (like the rest of QEMU).  
Instead of introducing YA hook, we can just switch kqemu to use 
anonymous memory and eliminate the special case.

If I recall correctly, the reason for using /dev/shm was concern that 
get_user_pages() didn't do the right thing for anonymous memory and the 
use of /dev/shm was a hack around that.  However, I'm not sure that was 
ever the case.  Certainly, with any sufficiently modern kernel 
get_user_pages() does what one would expect.  KVM uses get_user_pages() 
on anonymous memory in roughly the same way kqemu uses it now.

So I think it's safe to make the switch.  Fabrice, what do you think?

Regards,

Anthony Liguori

Glauber Costa wrote:
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  osdep.c |  111 ---------------------------------------------------------------
>  1 files changed, 0 insertions(+), 111 deletions(-)
>
> diff --git a/osdep.c b/osdep.c
> index 683aad0..31c96e6 100644
> --- a/osdep.c
> +++ b/osdep.c
> @@ -68,112 +68,9 @@ void qemu_vfree(void *ptr)
>
>  #else
>
> -#if defined(USE_KQEMU)
> -
> -#ifdef __OpenBSD__
> -#include <sys/param.h>
> -#include <sys/types.h>
> -#include <sys/mount.h>
> -#else
> -#include <sys/vfs.h>
> -#endif
> -
>  #include <sys/mman.h>
>  #include <fcntl.h>
>
> -static void *kqemu_vmalloc(size_t size)
> -{
> -    static int phys_ram_fd = -1;
> -    static int phys_ram_size = 0;
> -    void *ptr;
> -
> -#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
> -    int map_anon = MAP_ANON;
> -#else
> -    int map_anon = 0;
> -    const char *tmpdir;
> -    char phys_ram_file[1024];
> -#ifdef HOST_SOLARIS
> -    struct statvfs stfs;
> -#else
> -    struct statfs stfs;
> -#endif
> -
> -    if (phys_ram_fd < 0) {
> -        tmpdir = getenv("QEMU_TMPDIR");
> -        if (!tmpdir)
> -#ifdef HOST_SOLARIS
> -            tmpdir = "/tmp";
> -        if (statvfs(tmpdir, &stfs) == 0) {
> -#else
> -            tmpdir = "/dev/shm";
> -        if (statfs(tmpdir, &stfs) == 0) {
> -#endif
> -            int64_t free_space;
> -            int ram_mb;
> -
> -            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
> -            if ((ram_size + 8192 * 1024) >= free_space) {
> -                ram_mb = (ram_size / (1024 * 1024));
> -                fprintf(stderr,
> -                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
> -                        tmpdir, ram_mb);
> -                if (strcmp(tmpdir, "/dev/shm") == 0) {
> -                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
> -                            "mount -o remount,size=%dm /dev/shm\n",
> -                            ram_mb + 16);
> -                } else {
> -                    fprintf(stderr,
> -                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
> -                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
> -                            "temporary RAM file will be opened.\n");
> -                }
> -                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
> -                exit(1);
> -            }
> -        }
> -        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
> -                 tmpdir);
> -        phys_ram_fd = mkstemp(phys_ram_file);
> -        if (phys_ram_fd < 0) {
> -            fprintf(stderr,
> -                    "warning: could not create temporary file in '%s'.\n"
> -                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
> -                    "Using '/tmp' as fallback.\n",
> -                    tmpdir);
> -            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
> -                     "/tmp");
> -            phys_ram_fd = mkstemp(phys_ram_file);
> -            if (phys_ram_fd < 0) {
> -                fprintf(stderr, "Could not create temporary memory file '%s'\n",
> -                        phys_ram_file);
> -                exit(1);
> -            }
> -        }
> -        unlink(phys_ram_file);
> -    }
> -    size = (size + 4095) & ~4095;
> -    ftruncate(phys_ram_fd, phys_ram_size + size);
> -#endif /* !__OpenBSD__ */
> -    ptr = mmap(NULL,
> -               size,
> -               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
> -               phys_ram_fd, phys_ram_size);
> -    if (ptr == MAP_FAILED) {
> -        fprintf(stderr, "Could not map physical memory\n");
> -        exit(1);
> -    }
> -    phys_ram_size += size;
> -    return ptr;
> -}
> -
> -static void kqemu_vfree(void *ptr)
> -{
> -    /* may be useful some day, but currently we do not need to free */
> -}
> -
> -#endif
> -
>  void *qemu_memalign(size_t alignment, size_t size)
>  {
>  #if defined(_POSIX_C_SOURCE)
> @@ -193,10 +90,6 @@ void *qemu_memalign(size_t alignment, size_t size)
>  /* alloc shared memory pages */
>  void *qemu_vmalloc(size_t size)
>  {
> -#if defined(USE_KQEMU)
> -    if (kqemu_allowed)
> -        return kqemu_vmalloc(size);
> -#endif
>  #ifdef _BSD
>      return valloc(size);
>  #else
> @@ -206,10 +99,6 @@ void *qemu_vmalloc(size_t size)
>
>  void qemu_vfree(void *ptr)
>  {
> -#if defined(USE_KQEMU)
> -    if (kqemu_allowed)
> -        kqemu_vfree(ptr);
> -#endif
>      free(ptr);
>  }
>
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 02/32] protect exec-all.h frm multiple inclusion
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion Glauber Costa
@ 2008-10-23 13:52   ` Anthony Liguori
  0 siblings, 0 replies; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:52 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> Signed-off-by: Glauber Costa <glommer@redhat.com>
>   

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>  exec-all.h |    3 +++
>  1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/exec-all.h b/exec-all.h
> index 6609c9a..e3da98a 100644
> --- a/exec-all.h
> +++ b/exec-all.h
> @@ -18,6 +18,8 @@
>   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
>   */
>
> +#ifndef _EXEC_ALL_H_
> +#define _EXEC_ALL_H_
>  /* allow to see translation results - the slowdown should be negligible, so we leave it */
>  #define DEBUG_DISAS
>
> @@ -385,3 +387,4 @@ static inline int kqemu_is_ok(CPUState *env)
>  }
>
>  #endif
> +#endif
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 03/32] change definition of FILE for linux
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 03/32] change definition of FILE for linux Glauber Costa
@ 2008-10-23 13:52   ` Anthony Liguori
  2008-10-23 14:13     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:52 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> use _IO_FILE, as it seems to be the case.
>   

Why?  What is this fixing?

It seems to work fine today and I don't see how this is related to the 
series.

Regards,

Anthony Liguori

> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  dyngen-exec.h |    6 ++++++
>  1 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/dyngen-exec.h b/dyngen-exec.h
> index 9260b6f..826ff46 100644
> --- a/dyngen-exec.h
> +++ b/dyngen-exec.h
> @@ -27,6 +27,10 @@
>  #define _FILEDEFED
>  #endif
>
> +#ifdef __linux__
> +#define __FILE_defined
> +#endif
> +
>  /* NOTE: standard headers should be used with special care at this
>     point because host CPU registers are used as global variables. Some
>     host headers do not allow that. */
> @@ -84,6 +88,8 @@ typedef void * host_reg_t;
>
>  #ifdef _BSD
>  typedef struct __sFILE FILE;
> +#elif defined(__linux__)
> +typedef struct _IO_FILE FILE;
>  #else
>  typedef struct FILE FILE;
>  #endif
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 04/32] move kqemu_cpu_exec to kqemu.c
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c Glauber Costa
@ 2008-10-23 13:55   ` Anthony Liguori
  2008-10-23 14:21     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:55 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> Only pieces of code that are frame-safe can be moved.
> compute_all() is an example of a non-frame-safe calling.
> So it has to be done prior to calling kqemu_cpu_exec().
>
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  cpu-exec.c |   33 +++++++++++++--------------------
>  kqemu.c    |   18 +++++++++++++++++-
>  2 files changed, 30 insertions(+), 21 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 6d4dcdd..f06df26 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -336,27 +336,20 @@ int cpu_exec(CPUState *env1)
>                  env->exception_index = -1;
>              }
>  #ifdef USE_KQEMU
> -            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
> -                int ret;
> -                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
> -                ret = kqemu_cpu_exec(env);
> -                /* put eflags in CPU temporary format */
> -                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
> -                DF = 1 - (2 * ((env->eflags >> 10) & 1));
> -                CC_OP = CC_OP_EFLAGS;
> -                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
> -                if (ret == 1) {
> -                    /* exception */
> -                    longjmp(env->jmp_env, 1);
> -                } else if (ret == 2) {
> -                    /* softmmu execution needed */
> +            env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
>   

Can't do this unconditionally since you're now recomputing all condition 
flags even when kqemu is not in use.  So unfortunately I'm not sure the 
code can be cleaned up much more if compute_all() must stay in cpu_exec.

Regards,

Anthony Liguori

> +            ret = kqemu_cpu_exec(env);
> +            env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
> +            if (ret == 1) {
> +                /* exception */
> +                longjmp(env->jmp_env, 1);
> +            } else if (ret == 2) {
> +                /* softmmu execution needed */
> +            } else {
> +                if (env->interrupt_request != 0) {
> +                    /* hardware interrupt will be executed just after */
>                  } else {
> -                    if (env->interrupt_request != 0) {
> -                        /* hardware interrupt will be executed just after */
> -                    } else {
> -                        /* otherwise, we restart */
> -                        longjmp(env->jmp_env, 1);
> -                    }
> +                    /* otherwise, we restart */
> +                    longjmp(env->jmp_env, 1);
>                  }
>              }
>  #endif
> diff --git a/kqemu.c b/kqemu.c
> index 4783aa2..39938e0 100644
> --- a/kqemu.c
> +++ b/kqemu.c
> @@ -30,6 +30,7 @@
>  #ifdef HOST_SOLARIS
>  #include <sys/ioccom.h>
>  #endif
> +#include "exec.h"
>  #include <stdlib.h>
>  #include <stdio.h>
>  #include <stdarg.h>
> @@ -689,7 +690,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
>      sc->base = ksc->base;
>  }
>
> -int kqemu_cpu_exec(CPUState *env)
> +int kqemu_do_cpu_exec(CPUState *env)
>  {
>      struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
>      int ret, cpl, i;
> @@ -939,6 +940,21 @@ int kqemu_cpu_exec(CPUState *env)
>      return 0;
>  }
>
> +int kqemu_cpu_exec(CPUState *env)
> +{
> +
> +    int ret = 2;
> +    if (kqemu_is_ok(env) && env->interrupt_request == 0) {
> +        ret = kqemu_do_cpu_exec(env);
> +        /* put eflags in CPU temporary format */
> +        CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
> +        DF = 1 - (2 * ((env->eflags >> 10) & 1));
> +        CC_OP = CC_OP_EFLAGS;
> +    }
> +    return ret;
> +}
> +
> +
>  void kqemu_cpu_interrupt(CPUState *env)
>  {
>  #if defined(_WIN32)
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 05/32] use more meaningful values for kqemu_cpu_exec
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec Glauber Costa
@ 2008-10-23 13:57   ` Anthony Liguori
  2008-10-23 14:23     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:57 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> define constants that actually mean something instead of 1, 2, etc
>
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  cpu-exec.c |    4 ++--
>  exec-all.h |    4 ++++
>  kqemu.c    |   12 ++++++------
>  3 files changed, 12 insertions(+), 8 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index f06df26..88b7d6f 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -339,10 +339,10 @@ int cpu_exec(CPUState *env1)
>              env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
>              ret = kqemu_cpu_exec(env);
>              env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
> -            if (ret == 1) {
> +            if (ret == EXEC_EXIT_INTR) {
>                  /* exception */
>                  longjmp(env->jmp_env, 1);
> -            } else if (ret == 2) {
> +            } else if (ret == EXEC_EXIT_SOFTMMU) {
>                  /* softmmu execution needed */
>              } else {
>                  if (env->interrupt_request != 0) {
> diff --git a/exec-all.h b/exec-all.h
> index e3da98a..c10248b 100644
> --- a/exec-all.h
> +++ b/exec-all.h
> @@ -356,6 +356,10 @@ static inline int can_do_io(CPUState *env)
>  }
>  #endif
>
> +#define EXEC_EXIT_DONE 0
> +#define EXEC_EXIT_INTR 1
> +#define EXEC_EXIT_SOFTMMU 2
> +
>   

How about ACCEL_EXIT_?  These codes are accelerator specific after all.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 06/32] split kqemu_init into two
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 06/32] split kqemu_init into two Glauber Costa
@ 2008-10-23 13:58   ` Anthony Liguori
  2008-10-23 14:28     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 13:58 UTC (permalink / raw)
  To: Glauber Costa
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> we separate kqemu_init() into a part that depends on env,
> and other that does not. The later can be initialized earlier
>   

This patch seems harmless but I can't reasonably infer why this change 
is necessary.  What's the advantage of splitting the initialization into 
two parts?

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver Glauber Costa
@ 2008-10-23 14:00   ` Anthony Liguori
  0 siblings, 0 replies; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:00 UTC (permalink / raw)
  To: Glauber Costa
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> This patch introduces QEMUAccel, a placeholder for function pointers
> that aims at helping qemu to abstract accelerators such as kqemu and
> kvm (actually, the 'accelerator' name was proposed by avi kivity, since
> he loves referring to kvm that way).
>
> To begin with, the accelerator is given the opportunity to register a
> cpu_interrupt function, to be called after the raw cpu_interrupt.
> This has the side effect of, for the kqemu accelerator, calling kqemu_cpu_interrupt
> everytime, which didn't use to happen. But looking at the code, this seems safe to me.
>
> This patch applies on raw qemu.
>
>   

See my previous bit of feedback.  cpu_interrupt place to be hooking.  It 
really ought to be an io_window or cpu_loop_exit hook or something like 
that.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 10/32] turn info kqemu into generic info accelerator
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator Glauber Costa
@ 2008-10-23 14:03   ` Anthony Liguori
  2008-10-23 14:24     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:03 UTC (permalink / raw)
  To: Glauber Costa
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> Yet another accel field: info.
> From this point on, "info kqemu" is no more. "info accelerator" should
> be used instead.
>
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  accel.c   |    6 ++++++
>  accel.h   |    8 ++++++++
>  kqemu.c   |   26 ++++++++++++++++++++++++++
>  monitor.c |   35 ++++++++++++-----------------------
>  4 files changed, 52 insertions(+), 23 deletions(-)
>
> diff --git a/accel.c b/accel.c
> index 6776244..cb615d7 100644
> --- a/accel.c
> +++ b/accel.c
> @@ -8,6 +8,11 @@ int _accel_nop(void)
>      return 0;
>  }
>
> +int noaccel_info(CPUState *env, char *buf)
> +{
> +    return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
> +}
> +
>  #define accel_nop ((void *)_accel_nop)
>
>  /* Accelerator wrapper for the no-accel (raw qemu) case */
> @@ -16,5 +21,6 @@ QEMUAccel noaccel = {
>      .init_env = accel_nop,
>      .flush_cache = accel_nop,
>      .flush_page = accel_nop,
> +    .info = noaccel_info,
>  };
>
> diff --git a/accel.h b/accel.h
> index 935cfef..549ce01 100644
> --- a/accel.h
> +++ b/accel.h
> @@ -1,11 +1,14 @@
>  #ifndef _ACCEL_H_
>  #define _ACCEL_H_
>
> +#define MAX_INFO_BUF 1024
> +
>  typedef struct QEMUAccel {
>      void (*cpu_interrupt)(CPUState *env);
>      void (*init_env)(CPUState *env);
>      void (*flush_cache)(CPUState *env, int global);
>      void (*flush_page)(CPUState *env, target_ulong addr);
> +    int (*info)(CPUState *env, char *buf);
>  } QEMUAccel;
>
>  extern QEMUAccel *current_accel;
> @@ -35,4 +38,9 @@ static inline void accel_flush_page(CPUState *env, target_ulong addr)
>  {
>      current_accel->flush_page(env, addr);
>  }
> +
> +static inline int accel_info(CPUState *env, char *buf)
> +{
> +    return current_accel->info(env, buf);
> +}
>  #endif
> diff --git a/kqemu.c b/kqemu.c
> index 3f2433a..424d8f4 100644
> --- a/kqemu.c
> +++ b/kqemu.c
> @@ -1047,11 +1047,37 @@ static void qpi_init(void)
>                                   0x1000, qpi_io_memory);
>  }
>
> +static int kqemu_info(CPUState *env, char *buf)
> +{
> +    int val, len;
> +    int bufsiz = MAX_INFO_BUF;
>   

Why not just pass bufsiz as an argument to kqemu_info?

> +    if (accel_info(env, buf))
> +        term_printf(buf);
>   

You should do term_printf("%s", buf);  This is a common exploit if 
there's ever a chance that buf has user-originated data.  Therefore, 
it's good practice to always use ("%s", buf) instead of passing buf 
directly.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 0/32] New shot at accelerators
  2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
@ 2008-10-23 14:07   ` Glauber Costa
  2008-10-23 14:15     ` Avi Kivity
  0 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:07 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: aliguori, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 03:35:16PM +0200, Jan Kiszka wrote:
> Glauber Costa wrote:
> > Hi guys,
> >  
> > I'm sending here a new version of the accel patch. It comprises
> > the cleaned up version I've last sent, plus a few additions
> > 
> > You may want to pay special attention to the additions, since
> > they are newcomers to the series. To ease your job, they are:
> > 
> > 0001-use-anonymous-memory-for-kqemu.patch
> > 0002-protect-exec-all.h-frm-multiple-inclusion.patch
> > 0003-change-definition-of-FILE-for-linux.patch
> > 0005-use-more-meaningful-values-for-kqemu_cpu_exec.patch
> > 0025-provide-accel-hook-for-cpu_exec.patch
> > 0026-provide-two-accelerators-for-kqemu.patch
> > 0027-arch-specific-hooks-for-accelerator.patch
> > 0028-iret-arch-specific-accelerator.patch
> > 0029-sysret-sysexit-arch-specific-accelerator.patch
> > 0030-lcall-lret-arch-specific-accel-hooks.patch
> > 0031-remove-kqemu_is_ok-tests.patch
> > 0032-clean-up-kqemu-code.patch
> > 
> > git users can get a snapshot of it located at
> > 
> > git://git.kernel.org/pub/scm/virt/glommer/qemu-accel.git accel-v2
> > 
> > diffstat and OBP (One Big Patch ;-)) attached.
> > 
> 
> Careful question: Build-tested against other OSes beyond /The OS/ ;)?
No. I only have a Linux environment right now.
> 
> Jan
> 
> -- 
> Siemens AG, Corporate Technology, CT SE 2
> Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 03/32] change definition of FILE for linux
  2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:13     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:13 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 08:52:52AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> use _IO_FILE, as it seems to be the case.
>>   
>
> Why?  What is this fixing?
>
> It seems to work fine today and I don't see how this is related to the  
> series.

It's not possible to include exec.h into kqemu.c without it, because it conflicts
with virtually everything from stdio.h

The inclusion of exec.h is necessary for the cpu_exec patch, since we'll be using symbols
defined in that header. OTOH, those symbols are mostly macros that cast env->something, and
if really needed, I can use the env-> versions instead.

>
> Regards,
>
> Anthony Liguori
>
>> Signed-off-by: Glauber Costa <glommer@redhat.com>
>> ---
>>  dyngen-exec.h |    6 ++++++
>>  1 files changed, 6 insertions(+), 0 deletions(-)
>>
>> diff --git a/dyngen-exec.h b/dyngen-exec.h
>> index 9260b6f..826ff46 100644
>> --- a/dyngen-exec.h
>> +++ b/dyngen-exec.h
>> @@ -27,6 +27,10 @@
>>  #define _FILEDEFED
>>  #endif
>>
>> +#ifdef __linux__
>> +#define __FILE_defined
>> +#endif
>> +
>>  /* NOTE: standard headers should be used with special care at this
>>     point because host CPU registers are used as global variables. Some
>>     host headers do not allow that. */
>> @@ -84,6 +88,8 @@ typedef void * host_reg_t;
>>
>>  #ifdef _BSD
>>  typedef struct __sFILE FILE;
>> +#elif defined(__linux__)
>> +typedef struct _IO_FILE FILE;
>>  #else
>>  typedef struct FILE FILE;
>>  #endif
>>   
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 0/32] New shot at accelerators
  2008-10-23 14:07   ` Glauber Costa
@ 2008-10-23 14:15     ` Avi Kivity
  0 siblings, 0 replies; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 14:15 UTC (permalink / raw)
  To: Glauber Costa; +Cc: Jan Kiszka, aliguori, jes, qemu-devel, dmitry.baryshkov

Glauber Costa wrote:
>
> No. I only have a Linux environment right now.
>   

Surely you have a Windows VM somewhere?  It should be tested both as a 
guest and as a host.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 13:48   ` Anthony Liguori
@ 2008-10-23 14:17     ` Jan Kiszka
  2008-10-23 14:25       ` Anthony Liguori
  0 siblings, 1 reply; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 14:17 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, jes, qemu-devel, avi, dmitry.baryshkov

Anthony Liguori wrote:
> The idea behind this patch is that currently kqemu uses /dev/shm for
> memory allocations instead of anonymous memory (like the rest of QEMU). 
> Instead of introducing YA hook, we can just switch kqemu to use
> anonymous memory and eliminate the special case.
> 
> If I recall correctly, the reason for using /dev/shm was concern that
> get_user_pages() didn't do the right thing for anonymous memory and the
> use of /dev/shm was a hack around that.  However, I'm not sure that was
> ever the case.  Certainly, with any sufficiently modern kernel
> get_user_pages() does what one would expect.  KVM uses get_user_pages()
> on anonymous memory in roughly the same way kqemu uses it now.
> 
> So I think it's safe to make the switch.  Fabrice, what do you think?

This hack-around, was it purely Linux-motivated? Or did/do other OSes
have similar issues?

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 0/32] New shot at accelerators
@ 2008-10-23 14:18 Glauber Costa
  2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
                   ` (33 more replies)
  0 siblings, 34 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Hi guys,
 
I'm sending here a new version of the accel patch. It comprises
the cleaned up version I've last sent, plus a few additions

You may want to pay special attention to the additions, since
they are newcomers to the series. To ease your job, they are:

0001-use-anonymous-memory-for-kqemu.patch
0002-protect-exec-all.h-frm-multiple-inclusion.patch
0003-change-definition-of-FILE-for-linux.patch
0005-use-more-meaningful-values-for-kqemu_cpu_exec.patch
0025-provide-accel-hook-for-cpu_exec.patch
0026-provide-two-accelerators-for-kqemu.patch
0027-arch-specific-hooks-for-accelerator.patch
0028-iret-arch-specific-accelerator.patch
0029-sysret-sysexit-arch-specific-accelerator.patch
0030-lcall-lret-arch-specific-accel-hooks.patch
0031-remove-kqemu_is_ok-tests.patch
0032-clean-up-kqemu-code.patch

git users can get a snapshot of it located at

git://git.kernel.org/pub/scm/virt/glommer/qemu-accel.git accel-v2

diffstat and OBP (One Big Patch ;-)) attached.

------
 Makefile.target         |    2 +-
 accel.c                 |   51 +++++++++
 accel.h                 |  171 ++++++++++++++++++++++++++++
 cpu-all.h               |    9 +-
 cpu-exec.c              |   47 +++-----
 dyngen-exec.h           |    6 +
 exec-all.h              |   34 +-----
 exec.c                  |  115 ++++++++++----------
 hw/pc.c                 |   13 +--
 kqemu.c                 |  284 +++++++++++++++++++++++++++++++++++++++++++----
 kqemu.h                 |   21 ++++
 monitor.c               |   70 +++++-------
 osdep.c                 |  111 ------------------
 softmmu_template.h      |   10 +-
 sysemu.h                |    5 -
 target-i386/accel86.h   |   60 ++++++++++
 target-i386/cpu.h       |   13 --
 target-i386/helper.c    |    8 +-
 target-i386/op_helper.c |   52 ++-------
 vl.c                    |   93 ++++++----------
 20 files changed, 736 insertions(+), 439 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index e2edf9d..623ecd8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,7 @@ all: $(PROGS)
 #########################################################
 # cpu emulator library
 LIBOBJS=exec.o kqemu.o translate-all.o cpu-exec.o\
-        translate.o host-utils.o
+        translate.o host-utils.o accel.o
 ifdef CONFIG_DYNGEN_OP
 exec.o: dyngen-opc.h
 LIBOBJS+=op.o
diff --git a/accel.c b/accel.c
new file mode 100644
index 0000000..8d635f0
--- /dev/null
+++ b/accel.c
@@ -0,0 +1,51 @@
+#include "hw/hw.h"
+#include "exec-all.h"
+#include "accel.h"
+
+QEMUAccel *current_accel;
+QEMUCont *head = NULL;
+
+int _accel_nop(void)
+{
+    return 0;
+}
+
+int noaccel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
+}
+
+CPUState *noaccel_get_env(void)
+{
+    return qemu_mallocz(sizeof(CPUState));
+}
+
+int noaccel_cpu_exec(CPUState *env)
+{
+    return EXEC_EXIT_SOFTMMU;
+}
+
+#define accel_nop ((void *)_accel_nop)
+
+/* Accelerator wrapper for the no-accel (raw qemu) case */
+QEMUAccel noaccel = {
+    .name = "none",
+    .cpu_interrupt = accel_nop,
+    .init_env = accel_nop,
+    .get_env = noaccel_get_env,
+    .start = accel_nop,
+    .flush_cache = accel_nop,
+    .flush_page = accel_nop,
+    .info = noaccel_info,
+    .profile = accel_nop,
+    .set_notdirty = accel_nop,
+    .modify_page = accel_nop,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_ticks,
+#endif
+    .register_physical_memory = accel_nop,
+    .trace_io = accel_nop,
+    .break_loop = accel_nop,
+    .cpu_exec = noaccel_cpu_exec,
+};
+
diff --git a/accel.h b/accel.h
new file mode 100644
index 0000000..00a495c
--- /dev/null
+++ b/accel.h
@@ -0,0 +1,171 @@
+#ifndef _ACCEL_H_
+#define _ACCEL_H_
+
+#define MAX_INFO_BUF 1024
+
+typedef struct QEMUAccel {
+    char *name;
+    void (*cpu_interrupt)(CPUState *env);
+    CPUState *(*get_env)(void);
+    void (*init_env)(CPUState *env);
+    int (*start)(int cpus);
+    void (*flush_cache)(CPUState *env, int global);
+    void (*flush_page)(CPUState *env, target_ulong addr);
+    int (*info)(CPUState *env, char *buf);
+    int (*profile)(CPUState *env, char *buf);
+    void (*set_notdirty)(ram_addr_t addr);
+    void (*modify_page)(ram_addr_t addr, int dirty_flags);
+#ifndef CONFIG_USER_ONLY
+    uint64_t (*get_real_ticks)(void);
+#endif
+    void (*register_physical_memory)(uint64_t start_addr,
+                                     ram_addr_t size, ram_addr_t phys_offset);
+    void (*trace_io)(CPUState *env);
+    int (*break_loop)(CPUState *env);
+    int (*cpu_exec)(CPUState *env);
+    void *arch; /* arch-specific accel functions */
+} QEMUAccel;
+
+typedef struct QEMUCont {
+    QEMUAccel *acc;
+    int active;
+    struct QEMUCont *next;
+} QEMUCont;
+
+extern QEMUAccel *current_accel;
+extern QEMUAccel noaccel;
+#ifdef USE_KQEMU
+extern QEMUAccel kqemu_accel;
+extern QEMUAccel kqemu_kernel_accel;
+#endif
+
+extern QEMUCont *head;
+void *qemu_mallocz(size_t size);
+extern CPUState *noaccel_get_env(void);
+
+static inline int register_qemu_accel(QEMUAccel *accel)
+{
+    QEMUCont *new, *tmp, *last = NULL;
+
+    for (tmp = head, last; tmp; tmp = tmp->next) {
+        /* we disallow registering the same accelerator twice */
+        if (tmp->acc ==  accel)
+            return -1;
+
+        if (!tmp->next)
+            last = tmp;
+    }
+
+    new = qemu_mallocz(sizeof(*head));
+
+    new->acc = accel;
+    new->active = 0;
+    new->next = NULL;
+
+    if (!head)
+        head = new;
+    else
+        last->next = new;
+
+    return 0;
+}
+
+static inline QEMUCont *get_accel_head(void)
+{
+    return head;
+}
+
+static inline void accel_cpu_interrupt(CPUState *env)
+{
+    current_accel->cpu_interrupt(env);
+}
+
+static inline int accel_start(int cpus)
+{
+    int status = -1;
+    /* The top accelerator in the list gets tried first, but if it fails,
+     * keep trying until one of them succeeds or we exhaust the list */
+    QEMUCont *tmp = head;
+    while (tmp) {
+        if (tmp->acc && tmp->acc->start && (!(tmp->acc->start(cpus))) ) {
+            tmp->active = 1;
+            current_accel = tmp->acc;
+            status = 0;
+            break;
+        }
+        tmp = tmp->next;
+    }
+    return status;
+}
+
+static inline CPUState *accel_get_env(void)
+{
+    return current_accel->get_env();
+}
+
+static inline void accel_init_env(CPUState *env)
+{
+    current_accel->init_env(env);
+}
+
+static inline void accel_flush_cache(CPUState *env, int global)
+{
+    current_accel->flush_cache(env, global);
+}
+
+static inline void accel_flush_page(CPUState *env, target_ulong addr)
+{
+    current_accel->flush_page(env, addr);
+}
+
+static inline int accel_info(CPUState *env, char *buf)
+{
+    return current_accel->info(env, buf);
+}
+
+static inline int accel_profile(CPUState *env, char *buf)
+{
+   return current_accel->profile(env, buf);
+}
+
+static inline void accel_set_notdirty(target_ulong addr)
+{
+    current_accel->set_notdirty(addr);
+}
+
+static inline void accel_modify_page(target_ulong addr, int dirty_flags)
+{
+    current_accel->modify_page(addr, dirty_flags);
+}
+
+int64_t cpu_get_ticks(void);
+
+#ifndef CONFIG_USER_ONLY
+static inline uint64_t accel_get_real_ticks(void)
+{
+   return current_accel->get_real_ticks();
+}
+#endif
+
+static inline void accel_register_phys_mem(uint64_t start_addr,
+                                           ram_addr_t size,
+                                           ram_addr_t phys_offset)
+{
+    current_accel->register_physical_memory(start_addr, size, phys_offset);
+}
+
+static inline void accel_trace_io(CPUState *env)
+{
+    current_accel->trace_io(env);
+}
+
+static inline int accel_break_loop(CPUState *env)
+{
+    return current_accel->break_loop(env);
+}
+
+static inline int accel_cpu_exec(CPUState *env)
+{
+    return current_accel->cpu_exec(env);
+}
+#endif
diff --git a/cpu-all.h b/cpu-all.h
index cdd79bc..edefb45 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -863,6 +863,10 @@ extern ram_addr_t ram_size;
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
+/* this is a private version, meant for internal use of accelerators */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset);
 void cpu_register_physical_memory(target_phys_addr_t start_addr,
                                   ram_addr_t size,
                                   ram_addr_t phys_offset);
@@ -1077,14 +1081,9 @@ static inline int64_t profile_getclock(void)
     return cpu_get_real_ticks();
 }
 
-extern int64_t kqemu_time, kqemu_time_start;
 extern int64_t qemu_time, qemu_time_start;
 extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
 extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
 #endif
 
 #endif /* CPU_ALL_H */
diff --git a/cpu-exec.c b/cpu-exec.c
index 6d4dcdd..a0b6055 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -36,6 +36,7 @@
 #include <signal.h>
 #include <sys/ucontext.h>
 #endif
+#include "accel.h"
 
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
 // Work around ugly bugs in glibc that mangle global register contents
@@ -335,31 +336,23 @@ int cpu_exec(CPUState *env1)
                 }
                 env->exception_index = -1;
             }
-#ifdef USE_KQEMU
-            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
-                int ret;
-                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-                ret = kqemu_cpu_exec(env);
-                /* put eflags in CPU temporary format */
-                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                DF = 1 - (2 * ((env->eflags >> 10) & 1));
-                CC_OP = CC_OP_EFLAGS;
-                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                if (ret == 1) {
-                    /* exception */
-                    longjmp(env->jmp_env, 1);
-                } else if (ret == 2) {
-                    /* softmmu execution needed */
+
+            env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
+            ret = accel_cpu_exec(env);
+            env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+            if (ret == EXEC_EXIT_INTR) {
+                /* exception */
+                longjmp(env->jmp_env, 1);
+            } else if (ret == EXEC_EXIT_SOFTMMU) {
+                /* softmmu execution needed */
+            } else {
+                if (env->interrupt_request != 0) {
+                    /* hardware interrupt will be executed just after */
                 } else {
-                    if (env->interrupt_request != 0) {
-                        /* hardware interrupt will be executed just after */
-                    } else {
-                        /* otherwise, we restart */
-                        longjmp(env->jmp_env, 1);
-                    }
+                    /* otherwise, we restart */
+                    longjmp(env->jmp_env, 1);
                 }
             }
-#endif
 
             next_tb = 0; /* force lookup of first TB */
             for(;;) {
@@ -605,7 +598,7 @@ int cpu_exec(CPUState *env1)
                 {
                     if (next_tb != 0 &&
 #ifdef USE_KQEMU
-                        (env->kqemu_enabled != 2) &&
+                        (!kqemu_kernel_enabled(env)) &&
 #endif
                         tb->page_addr[1] == -1) {
                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
@@ -653,13 +646,7 @@ int cpu_exec(CPUState *env1)
                 }
                 /* reset soft MMU for next block (it can currently
                    only be set by a memory fault) */
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
-                if (kqemu_is_ok(env) &&
-                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
-                    cpu_loop_exit();
-                }
-#endif
+                accel_break_loop(env);
             } /* for(;;) */
         } else {
             env_to_regs();
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 9260b6f..826ff46 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -27,6 +27,10 @@
 #define _FILEDEFED
 #endif
 
+#ifdef __linux__
+#define __FILE_defined
+#endif
+
 /* NOTE: standard headers should be used with special care at this
    point because host CPU registers are used as global variables. Some
    host headers do not allow that. */
@@ -84,6 +88,8 @@ typedef void * host_reg_t;
 
 #ifdef _BSD
 typedef struct __sFILE FILE;
+#elif defined(__linux__)
+typedef struct _IO_FILE FILE;
 #else
 typedef struct FILE FILE;
 #endif
diff --git a/exec-all.h b/exec-all.h
index 6609c9a..fa4a4eb 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _EXEC_ALL_H_
+#define _EXEC_ALL_H_
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
 
@@ -354,34 +356,8 @@ static inline int can_do_io(CPUState *env)
 }
 #endif
 
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
-
-#define MSR_QPI_COMMBASE 0xfabe0010
-
-int kqemu_init(CPUState *env);
-int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
-void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
-                        ram_addr_t phys_offset);
-void kqemu_cpu_interrupt(CPUState *env);
-void kqemu_record_dump(void);
-
-extern uint32_t kqemu_comm_base;
-
-static inline int kqemu_is_ok(CPUState *env)
-{
-    return(env->kqemu_enabled &&
-           (env->cr[0] & CR0_PE_MASK) &&
-           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
-           (env->eflags & IF_MASK) &&
-           !(env->eflags & VM_MASK) &&
-           (env->kqemu_enabled == 2 ||
-            ((env->hflags & HF_CPL_MASK) == 3 &&
-             (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
+#define EXEC_EXIT_DONE 0
+#define EXEC_EXIT_INTR 1
+#define EXEC_EXIT_SOFTMMU 2
 
 #endif
diff --git a/exec.c b/exec.c
index f1fcec8..7fe7eeb 100644
--- a/exec.c
+++ b/exec.c
@@ -43,6 +43,8 @@
 #include <qemu.h>
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
 //#define DEBUG_TLB
@@ -524,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 }
 #endif
 
-void cpu_exec_init(CPUState *env)
+int next_cpu_index(void)
 {
     CPUState **penv;
-    int cpu_index;
+    int cpu_index = 0;
 
-    env->next_cpu = NULL;
     penv = &first_cpu;
-    cpu_index = 0;
+
     while (*penv != NULL) {
         penv = (CPUState **)&(*penv)->next_cpu;
         cpu_index++;
     }
-    env->cpu_index = cpu_index;
+    return cpu_index;
+}
+
+void cpu_exec_init(CPUState *env)
+{
+    env->next_cpu = NULL;
+    env->cpu_index = next_cpu_index();
     env->nb_watchpoints = 0;
-    *penv = env;
+    if (env->cpu_index == 0)
+        first_cpu = env;
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
+    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
                     cpu_common_save, cpu_common_load, env);
-    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
+    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
                     cpu_save, cpu_load, env);
 #endif
 }
@@ -1427,6 +1435,7 @@ void cpu_single_step(CPUState *env, int enabled)
         tb_flush(env);
     }
 #endif
+    accel_cpu_interrupt(env);
 }
 
 /* enable or disable low levels log */
@@ -1678,11 +1687,8 @@ void tlb_flush(CPUState *env, int flush_global)
 
     memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush(env, flush_global);
-    }
-#endif
+    accel_flush_cache(env, flush_global);
+
     tlb_flush_count++;
 }
 
@@ -1724,11 +1730,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
 
     tlb_flush_jmp_cache(env, addr);
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush_page(env, addr);
-    }
-#endif
+    accel_flush_page(env, addr);
 }
 
 /* update the TLBs so that writes to code in the virtual page 'addr'
@@ -1775,18 +1777,14 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     if (length == 0)
         return;
     len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env->kqemu_enabled) {
-        ram_addr_t addr;
-        addr = start;
-        for(i = 0; i < len; i++) {
-            kqemu_set_notdirty(env, addr);
-            addr += TARGET_PAGE_SIZE;
-        }
+
+    ram_addr_t addr;
+    addr = start;
+    for(i = 0; i < len; i++) {
+        accel_set_notdirty(addr);
+        addr += TARGET_PAGE_SIZE;
     }
-#endif
+
     mask = ~dirty_flags;
     p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
     for(i = 0; i < len; i++)
@@ -2191,12 +2189,13 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
         }                                                               \
     } while (0)
 
-/* register physical memory. 'size' must be a multiple of the target
-   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
-   io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
-                                  ram_addr_t size,
-                                  ram_addr_t phys_offset)
+/* Use this version of cpu registering physical memory in accel-specific code. It exists
+ * to avoid chicken and egg problems with code that might need to register memory in qemu,
+ * but not with the underlying accelerator
+ */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                    ram_addr_t size,
+                                    ram_addr_t phys_offset)
 {
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
@@ -2204,13 +2203,6 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     ram_addr_t orig_size = size;
     void *subpage;
 
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env->kqemu_enabled) {
-        kqemu_set_phys_mem(start_addr, size, phys_offset);
-    }
-#endif
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + (target_phys_addr_t)size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
@@ -2268,6 +2260,18 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     }
 }
 
+/* register physical memory. 'size' must be a multiple of the target
+   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
+   io memory page */
+void cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset)
+{
+    accel_register_phys_mem(start_addr, size, phys_offset);
+
+    __cpu_register_physical_memory(start_addr, size, phys_offset);
+}
+
 /* XXX: temporary until new memory mapping API */
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
 {
@@ -2383,12 +2387,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stb_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2408,12 +2411,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stw_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2433,12 +2435,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stl_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
diff --git a/hw/pc.c b/hw/pc.c
index 34683e7..2f56c1f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -33,6 +33,7 @@
 #include "boards.h"
 #include "console.h"
 #include "fw_cfg.h"
+#include "accel.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -75,17 +76,7 @@ static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
 /* TSC handling */
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
-    /* Note: when using kqemu, it is more logical to return the host TSC
-       because kqemu does not trap the RDTSC instruction for
-       performance reasons */
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        return cpu_get_real_ticks();
-    } else
-#endif
-    {
-        return cpu_get_ticks();
-    }
+    return accel_get_real_ticks();
 }
 
 /* SMM support */
diff --git a/kqemu.c b/kqemu.c
index 4783aa2..58a149b 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -30,6 +30,7 @@
 #ifdef HOST_SOLARIS
 #include <sys/ioccom.h>
 #endif
+#include "exec.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -44,12 +45,21 @@
 
 #ifdef USE_KQEMU
 
+#define KQEMU_USER 1
+#define KQEMU_KERNEL 2
+
+static int kqemu_state;
 #define DEBUG
 //#define PROFILE
 
 #include <unistd.h>
 #include <fcntl.h>
 #include "kqemu.h"
+#include "accel86.h"
+
+#ifdef CONFIG_PROFILER
+#include "qemu-timer.h" /* for ticks_per_sec */
+#endif
 
 #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"
@@ -69,11 +79,6 @@ int kqemu_fd = KQEMU_INVALID_FD;
 #define kqemu_closefd(x) close(x)
 #endif
 
-/* 0 = not allowed
-   1 = user kqemu
-   2 = kernel kqemu
-*/
-int kqemu_allowed = 1;
 uint64_t *pages_to_flush;
 unsigned int nb_pages_to_flush;
 uint64_t *ram_pages_to_update;
@@ -84,6 +89,13 @@ uint8_t *modified_ram_pages_table;
 int qpi_io_memory;
 uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
 
+static inline int cpu_get_time_fast(void)
+{
+    int low, high;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    return low;
+}
+
 #define cpuid(index, eax, ebx, ecx, edx) \
   asm volatile ("cpuid" \
                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
@@ -113,6 +125,19 @@ static int is_cpuid_supported(void)
 }
 #endif
 
+/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
+ * altogether
+ */
+int kqemu_is_enabled(CPUState *env)
+{
+    return kqemu_state == KQEMU_USER;
+}
+
+int kqemu_kernel_enabled(CPUState *env)
+{
+    return kqemu_state == KQEMU_KERNEL;
+}
+
 static void kqemu_update_cpuid(CPUState *env)
 {
     int critical_features_mask, features, ext_features, ext_features_mask;
@@ -150,7 +175,9 @@ static void kqemu_update_cpuid(CPUState *env)
        accelerated code */
 }
 
-int kqemu_init(CPUState *env)
+QEMUAccel kqemu_accel;
+
+static int kqemu_do_start(int cpus)
 {
     struct kqemu_init kinit;
     int ret, version;
@@ -158,7 +185,7 @@ int kqemu_init(CPUState *env)
     DWORD temp;
 #endif
 
-    if (!kqemu_allowed)
+    if (cpus > 1)
         return -1;
 
 #ifdef _WIN32
@@ -230,8 +257,6 @@ int kqemu_init(CPUState *env)
         kqemu_fd = KQEMU_INVALID_FD;
         return -1;
     }
-    kqemu_update_cpuid(env);
-    env->kqemu_enabled = kqemu_allowed;
     nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;
 
@@ -239,7 +264,24 @@ int kqemu_init(CPUState *env)
     return 0;
 }
 
-void kqemu_flush_page(CPUState *env, target_ulong addr)
+static int kqemu_start(int cpus)
+{
+    kqemu_state = KQEMU_USER;
+    return kqemu_do_start(cpus);
+}
+
+static int kqemu_start_kernel(int cpus)
+{
+    kqemu_state = KQEMU_KERNEL;
+    return kqemu_do_start(cpus);
+}
+
+static void kqemu_init_env(CPUState *env)
+{
+    kqemu_update_cpuid(env);
+}
+
+static void kqemu_flush_page(CPUState *env, target_ulong addr)
 {
 #if defined(DEBUG)
     if (loglevel & CPU_LOG_INT) {
@@ -252,7 +294,7 @@ void kqemu_flush_page(CPUState *env, target_ulong addr)
         pages_to_flush[nb_pages_to_flush++] = addr;
 }
 
-void kqemu_flush(CPUState *env, int global)
+static void kqemu_flush(CPUState *env, int global)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -262,7 +304,7 @@ void kqemu_flush(CPUState *env, int global)
     nb_pages_to_flush = KQEMU_FLUSH_ALL;
 }
 
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_set_notdirty(ram_addr_t ram_addr)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -291,7 +333,7 @@ static void kqemu_reset_modified_ram_pages(void)
     nb_modified_ram_pages = 0;
 }
 
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_modify_page(ram_addr_t ram_addr, int dirty_flags)
 {
     unsigned long page_index;
     int ret;
@@ -299,6 +341,8 @@ void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
     DWORD temp;
 #endif
 
+    if ((dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
+        return;
     page_index = ram_addr >> TARGET_PAGE_BITS;
     if (!modified_ram_pages_table[page_index]) {
 #if 0
@@ -689,7 +733,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
     sc->base = ksc->base;
 }
 
-int kqemu_cpu_exec(CPUState *env)
+static int kqemu_do_cpu_exec(CPUState *env)
 {
     struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
     int ret, cpl, i;
@@ -749,7 +793,7 @@ int kqemu_cpu_exec(CPUState *env)
     cpl = (env->hflags & HF_CPL_MASK);
     kenv->cpl = cpl;
     kenv->nb_pages_to_flush = nb_pages_to_flush;
-    kenv->user_only = (env->kqemu_enabled == 1);
+    kenv->user_only = kqemu_is_enabled(env);
     kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
     nb_ram_pages_to_update = 0;
     kenv->nb_modified_ram_pages = nb_modified_ram_pages;
@@ -891,7 +935,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
         env->exception_index = ret & 0xff;
         env->error_code = kenv->error_code;
@@ -907,7 +951,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if (ret == KQEMU_RET_INTR) {
 #ifdef CONFIG_PROFILER
         kqemu_ret_intr_count++;
@@ -917,7 +961,7 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 0;
+        return EXEC_EXIT_DONE;
     } else if (ret == KQEMU_RET_SOFTMMU) {
 #ifdef CONFIG_PROFILER
         {
@@ -930,16 +974,31 @@ int kqemu_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 2;
+        return EXEC_EXIT_SOFTMMU;
     } else {
         cpu_dump_state(env, stderr, fprintf, 0);
         fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
         exit(1);
     }
-    return 0;
+    return EXEC_EXIT_DONE;
 }
 
-void kqemu_cpu_interrupt(CPUState *env)
+static int kqemu_cpu_exec(CPUState *env)
+{
+
+    int ret = EXEC_EXIT_SOFTMMU;
+    if (kqemu_kernel_flags_ok(env) && env->interrupt_request == 0) {
+        ret = kqemu_do_cpu_exec(env);
+        /* put eflags in CPU temporary format */
+        CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+        DF = 1 - (2 * ((env->eflags >> 10) & 1));
+        CC_OP = CC_OP_EFLAGS;
+    }
+    return ret;
+}
+
+
+static void kqemu_cpu_interrupt(CPUState *env)
 {
 #if defined(_WIN32)
     /* cancelling the I/O request causes KQEMU to finish executing the
@@ -1019,7 +1078,188 @@ static void qpi_init(void)
     qpi_io_memory = cpu_register_io_memory(0, 
                                            qpi_mem_read, 
                                            qpi_mem_write, NULL);
-    cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
+    __cpu_register_physical_memory(kqemu_comm_base & ~0xfff,
                                  0x1000, qpi_io_memory);
 }
+
+static int kqemu_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user code\n");
+}
+
+static int kqemu_kernel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user and kernel code\n");
+}
+
+int64_t kqemu_time;
+int64_t kqemu_exec_count;
+int64_t kqemu_ret_int_count;
+int64_t kqemu_ret_excp_count;
+int64_t kqemu_ret_intr_count;
+extern int64_t qemu_time;
+
+static int kqemu_profile(CPUState *env, char *buf)
+{
+    int len = 0;
+#ifdef CONFIG_PROFILER
+    len = sprintf(buf, "kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64
+                        " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
+                kqemu_time, kqemu_time / (double)ticks_per_sec,
+                kqemu_time / qemu_time * 100.0,
+                kqemu_exec_count,
+                kqemu_ret_int_count,
+                kqemu_ret_excp_count,
+                kqemu_ret_intr_count);
+
+    kqemu_time = 0;
+    kqemu_exec_count = 0;
+    kqemu_ret_int_count = 0;
+    kqemu_ret_excp_count = 0;
+    kqemu_ret_intr_count = 0;
+    kqemu_record_dump();
+#endif
+    return len;
+}
+
+static void kqemu_trace_io(CPUState *env)
+{
+    if (env)
+        kqemu_cpu_field(env,last_io_time) = cpu_get_time_fast();
+}
+
+#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
+
+static inline int kqemu_flags_ok(CPUState *env)
+{
+    return((env->cr[0] & CR0_PE_MASK) &&
+           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
+           (env->eflags & IF_MASK) &&
+           !(env->eflags & VM_MASK));
+}
+
+static inline int kqemu_kernel_flags_ok(CPUState *env)
+{
+    return (kqemu_flags_ok(env) && (kqemu_kernel_enabled(env) ||
+            ((env->hflags & HF_CPL_MASK) == 3 &&
+             (env->eflags & IOPL_MASK) != IOPL_MASK)));
+
+}
+
+static int kqemu_break_loop(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env) &&
+        (cpu_get_time_fast() - kqemu_cpu_field(env,last_io_time)) >= MIN_CYCLE_BEFORE_SWITCH) {
+        return 1;
+    }
+    return 0;
+}
+
+static CPUState *kqemu_get_env(void)
+{
+    KQEMUCPUState *kenv;
+    kenv = qemu_mallocz(sizeof(KQEMUCPUState));
+    return &kenv->env;
+}
+
+static int kqemu_get_msr(int msr, uint64_t *val)
+{
+    int ret = -1;
+    switch (msr) {
+    case MSR_QPI_COMMBASE:
+        val = kqemu_comm_base;
+        ret = 0;
+        break;
+    }
+    return ret;
+}
+
+static int kqemu_set_msr(int msr, target_ulong val)
+{
+    return -1;
+}
+
+static void kqemu_interrupt_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+static void kqemu_syscall_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        if (env->hflags & HF_LMA_MASK)
+            CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+static void kqemu_long_exit_loop(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
+QEMUAccel86 kqemu_accel86 = {
+    .get_msr = kqemu_get_msr,
+    .set_msr = kqemu_set_msr,
+    .interrupt_return = kqemu_interrupt_return,
+    .syscall_return = kqemu_syscall_return,
+    .long_call = kqemu_long_exit_loop,
+    .long_ret = kqemu_long_exit_loop,
+};
+
+QEMUAccel kqemu_accel = {
+    .name = "KQEMU",
+    .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env,
+    .get_env = kqemu_get_env,
+    .start = kqemu_start,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
+    .info = kqemu_info,
+    .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    /* Note: when using kqemu, it is more logical to return the host TSC
+       because kqemu does not trap the RDTSC instruction for
+       performance reasons */
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
+    .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
+};
+
+QEMUAccel kqemu_kernel_accel = {
+    .name = "kernel-KQEMU",
+    .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env,
+    .get_env = kqemu_get_env,
+    .start = kqemu_start_kernel,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
+    .info = kqemu_kernel_info,
+    .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
+    .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
+};
+
 #endif
diff --git a/kqemu.h b/kqemu.h
index ed25c75..4152fbd 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -32,6 +32,12 @@
 
 #define KQEMU_VERSION 0x010400
 
+extern int64_t kqemu_time, kqemu_time_start;
+extern int64_t kqemu_exec_count;
+extern int64_t kqemu_ret_int_count;
+extern int64_t kqemu_ret_excp_count;
+extern int64_t kqemu_ret_intr_count;
+
 struct kqemu_segment_cache {
     uint16_t selector;
     uint16_t padding1;
@@ -151,4 +157,19 @@ struct kqemu_phys_mem {
 #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
 #endif
 
+int kqemu_is_enabled(CPUState *env);
+int kqemu_kernel_enabled(CPUState *env);
+
+typedef struct KQEMUCPUstate {
+    int last_io_time;
+    CPUState env;
+} KQEMUCPUState;
+
+#define kqemu_cpu_field(env, field) (*({ \
+    KQEMUCPUState *__c = container_of(env, KQEMUCPUState, env); \
+    &__c->field; }))
+
+#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
+
+#define MSR_QPI_COMMBASE 0xfabe0010
 #endif /* KQEMU_H */
diff --git a/monitor.c b/monitor.c
index f0a0bc3..fe915d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -34,6 +34,7 @@
 #include "block.h"
 #include "audio/audio.h"
 #include "disas.h"
+#include "accel.h"
 #include <dirent.h>
 #include "qemu-timer.h"
 #include "migration.h"
@@ -1233,49 +1234,42 @@ static void mem_info(void)
 }
 #endif
 
-static void do_info_kqemu(void)
+static int do_accel_do_list(void)
 {
-#ifdef USE_KQEMU
+    QEMUCont *tmp;
+    for (tmp= get_accel_head(); tmp != NULL; tmp = tmp->next)
+    {
+        term_printf("%c %s\n", tmp->active ? '*' : ' ', tmp->acc->name);
+    }
+}
+
+static void do_info_accelerator(void)
+{
+    char buf[MAX_INFO_BUF];
     CPUState *env;
-    int val;
-    val = 0;
+
     env = mon_get_cpu();
+
     if (!env) {
         term_printf("No cpu initialized yet");
         return;
     }
-    val = env->kqemu_enabled;
-    term_printf("kqemu support: ");
-    switch(val) {
-    default:
-    case 0:
-        term_printf("disabled\n");
-        break;
-    case 1:
-        term_printf("enabled for user code\n");
-        break;
-    case 2:
-        term_printf("enabled for user and kernel code\n");
-        break;
-    }
-#else
-    term_printf("kqemu support: not compiled\n");
-#endif
+
+    do_accel_do_list();
+    if (accel_info(env, buf))
+        term_printf(buf);
 }
 
 #ifdef CONFIG_PROFILER
 
-int64_t kqemu_time;
 int64_t qemu_time;
-int64_t kqemu_exec_count;
 int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
 static void do_info_profile(void)
 {
     int64_t total;
+    char buf[MAX_BUF];
+    CPUState *env = mon_get_cpu();
+
     total = qemu_time;
     if (total == 0)
         total = 1;
@@ -1283,24 +1277,12 @@ static void do_info_profile(void)
                 dev_time, dev_time / (double)ticks_per_sec);
     term_printf("qemu time   %" PRId64 " (%0.3f)\n",
                 qemu_time, qemu_time / (double)ticks_per_sec);
-    term_printf("kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
-                kqemu_time, kqemu_time / (double)ticks_per_sec,
-                kqemu_time / (double)total * 100.0,
-                kqemu_exec_count,
-                kqemu_ret_int_count,
-                kqemu_ret_excp_count,
-                kqemu_ret_intr_count);
+    if (accel_profile(env, buf))
+        term_printf(buf);
     qemu_time = 0;
-    kqemu_time = 0;
-    kqemu_exec_count = 0;
     dev_time = 0;
-    kqemu_ret_int_count = 0;
-    kqemu_ret_excp_count = 0;
-    kqemu_ret_intr_count = 0;
-#ifdef USE_KQEMU
-    kqemu_record_dump();
-#endif
 }
+
 #else
 static void do_info_profile(void)
 {
@@ -1493,8 +1475,8 @@ static const term_cmd_t info_cmds[] = {
 #endif
     { "jit", "", do_info_jit,
       "", "show dynamic compiler info", },
-    { "kqemu", "", do_info_kqemu,
-      "", "show kqemu information", },
+    { "accelerator", "", do_info_accelerator,
+      "", "show accelerator information", },
     { "usb", "", usb_info,
       "", "show guest USB devices", },
     { "usbhost", "", usb_host_info,
diff --git a/osdep.c b/osdep.c
index 683aad0..31c96e6 100644
--- a/osdep.c
+++ b/osdep.c
@@ -68,112 +68,9 @@ void qemu_vfree(void *ptr)
 
 #else
 
-#if defined(USE_KQEMU)
-
-#ifdef __OpenBSD__
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#else
-#include <sys/vfs.h>
-#endif
-
 #include <sys/mman.h>
 #include <fcntl.h>
 
-static void *kqemu_vmalloc(size_t size)
-{
-    static int phys_ram_fd = -1;
-    static int phys_ram_size = 0;
-    void *ptr;
-
-#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
-    int map_anon = MAP_ANON;
-#else
-    int map_anon = 0;
-    const char *tmpdir;
-    char phys_ram_file[1024];
-#ifdef HOST_SOLARIS
-    struct statvfs stfs;
-#else
-    struct statfs stfs;
-#endif
-
-    if (phys_ram_fd < 0) {
-        tmpdir = getenv("QEMU_TMPDIR");
-        if (!tmpdir)
-#ifdef HOST_SOLARIS
-            tmpdir = "/tmp";
-        if (statvfs(tmpdir, &stfs) == 0) {
-#else
-            tmpdir = "/dev/shm";
-        if (statfs(tmpdir, &stfs) == 0) {
-#endif
-            int64_t free_space;
-            int ram_mb;
-
-            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
-            if ((ram_size + 8192 * 1024) >= free_space) {
-                ram_mb = (ram_size / (1024 * 1024));
-                fprintf(stderr,
-                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
-                        tmpdir, ram_mb);
-                if (strcmp(tmpdir, "/dev/shm") == 0) {
-                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
-                            "mount -o remount,size=%dm /dev/shm\n",
-                            ram_mb + 16);
-                } else {
-                    fprintf(stderr,
-                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
-                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
-                            "temporary RAM file will be opened.\n");
-                }
-                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
-                exit(1);
-            }
-        }
-        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                 tmpdir);
-        phys_ram_fd = mkstemp(phys_ram_file);
-        if (phys_ram_fd < 0) {
-            fprintf(stderr,
-                    "warning: could not create temporary file in '%s'.\n"
-                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
-                    "Using '/tmp' as fallback.\n",
-                    tmpdir);
-            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                     "/tmp");
-            phys_ram_fd = mkstemp(phys_ram_file);
-            if (phys_ram_fd < 0) {
-                fprintf(stderr, "Could not create temporary memory file '%s'\n",
-                        phys_ram_file);
-                exit(1);
-            }
-        }
-        unlink(phys_ram_file);
-    }
-    size = (size + 4095) & ~4095;
-    ftruncate(phys_ram_fd, phys_ram_size + size);
-#endif /* !__OpenBSD__ */
-    ptr = mmap(NULL,
-               size,
-               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
-               phys_ram_fd, phys_ram_size);
-    if (ptr == MAP_FAILED) {
-        fprintf(stderr, "Could not map physical memory\n");
-        exit(1);
-    }
-    phys_ram_size += size;
-    return ptr;
-}
-
-static void kqemu_vfree(void *ptr)
-{
-    /* may be useful some day, but currently we do not need to free */
-}
-
-#endif
-
 void *qemu_memalign(size_t alignment, size_t size)
 {
 #if defined(_POSIX_C_SOURCE)
@@ -193,10 +90,6 @@ void *qemu_memalign(size_t alignment, size_t size)
 /* alloc shared memory pages */
 void *qemu_vmalloc(size_t size)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        return kqemu_vmalloc(size);
-#endif
 #ifdef _BSD
     return valloc(size);
 #else
@@ -206,10 +99,6 @@ void *qemu_vmalloc(size_t size)
 
 void qemu_vfree(void *ptr)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        kqemu_vfree(ptr);
-#endif
     free(ptr);
 }
 
diff --git a/softmmu_template.h b/softmmu_template.h
index 98dd378..4945352 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -47,6 +47,8 @@
 #define ADDR_READ addr_read
 #endif
 
+#include "accel.h"
+
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                         int mmu_idx,
                                                         void *retaddr);
@@ -75,9 +77,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
     res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return res;
 }
 
@@ -220,9 +220,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
     io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
diff --git a/sysemu.h b/sysemu.h
index 976fecc..5a19626 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -99,11 +99,6 @@ extern int semihosting_enabled;
 extern int old_param;
 extern const char *bootp_filename;
 
-
-#ifdef USE_KQEMU
-extern int kqemu_allowed;
-#endif
-
 #define MAX_OPTION_ROMS 16
 extern const char *option_rom[MAX_OPTION_ROMS];
 extern int nb_option_roms;
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
new file mode 100644
index 0000000..a7ba39b
--- /dev/null
+++ b/target-i386/accel86.h
@@ -0,0 +1,60 @@
+#ifndef _ACCEL_86_H_
+#define _ACCEL_86_H_
+
+#include "accel.h"
+
+typedef struct QEMUAccel86 {
+	int (*get_msr)(int msr, uint64_t *value);
+	int (*set_msr)(int msr, uint64_t value);
+    void (*interrupt_return)(CPUState *env);
+    void (*syscall_return)(CPUState *env);
+    void (*long_call)(CPUState *env);
+    void (*long_ret)(CPUState *env);
+} QEMUAccel86;
+
+#define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
+
+static inline int accel_get_msr(int msr, uint64_t *value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->get_msr(msr, value);
+}
+
+static inline int accel_set_msr(int msr, uint64_t value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->set_msr(msr, value);
+}
+
+static inline void accel_interrupt_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->interrupt_return(env);
+}
+
+static inline void accel_syscall_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+static inline void accel_long_call(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+static inline void accel_long_ret(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+#endif
+
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3c11e0f..e5e91cc 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -606,10 +606,6 @@ typedef struct CPUX86State {
     uint32_t cpuid_ext3_features;
     uint32_t cpuid_apic_id;
 
-#ifdef USE_KQEMU
-    int kqemu_enabled;
-    int last_io_time;
-#endif
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;
@@ -727,15 +723,6 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 #define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 
-#ifdef USE_KQEMU
-static inline int cpu_get_time_fast(void)
-{
-    int low, high;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    return low;
-}
-#endif
-
 #define TARGET_PAGE_BITS 12
 
 #define CPUState CPUX86State
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c2e1a88..5ff051f 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -30,6 +30,8 @@
 #include "svm.h"
 #include "qemu-common.h"
 
+#include "accel.h"
+
 //#define DEBUG_MMU
 
 static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
@@ -96,7 +98,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     CPUX86State *env;
     static int inited;
 
-    env = qemu_mallocz(sizeof(CPUX86State));
+    env = accel_get_env();
     if (!env)
         return NULL;
     cpu_exec_init(env);
@@ -112,9 +114,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
         return NULL;
     }
     cpu_reset(env);
-#ifdef USE_KQEMU
-    kqemu_init(env);
-#endif
+    accel_init_env(env);
     return env;
 }
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index ebb5824..addd42a 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -20,6 +20,7 @@
 #define CPU_NO_GLOBAL_REGS
 #include "exec.h"
 #include "host-utils.h"
+#include "accel86.h"
 
 //#define DEBUG_PCALL
 
@@ -1103,14 +1104,7 @@ void helper_sysret(int dflag)
         env->eflags |= IF_MASK;
         cpu_x86_set_cpl(env, 3);
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        if (env->hflags & HF_LMA_MASK)
-            CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_syscall_return(env);
 }
 
 /* real mode interrupt */
@@ -2623,12 +2617,7 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
         SET_ESP(sp, sp_mask);
         EIP = offset;
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_call(env);
 }
 
 /* real and vm86 mode iret */
@@ -2917,24 +2906,14 @@ void helper_iret_protected(int shift, int next_eip)
         helper_ret_protected(shift, 1, 0);
     }
     env->hflags2 &= ~HF2_NMI_MASK;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+
+    accel_interrupt_return(env);
 }
 
 void helper_lret_protected(int shift, int addend)
 {
     helper_ret_protected(shift, 0, addend);
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_ret(env);
 }
 
 void helper_sysenter(void)
@@ -3007,12 +2986,6 @@ void helper_sysexit(int dflag)
     }
     ESP = ECX;
     EIP = EDX;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 #if defined(CONFIG_USER_ONLY)
@@ -3262,18 +3235,9 @@ void helper_rdmsr(void)
         val = env->kernelgsbase;
         break;
 #endif
-#ifdef USE_KQEMU
-    case MSR_QPI_COMMBASE:
-        if (env->kqemu_enabled) {
-            val = kqemu_comm_base;
-        } else {
-            val = 0;
-        }
-        break;
-#endif
     default:
-        /* XXX: exception ? */
-        val = 0;
+        if (accel_get_msr((uint32_t)ECX, &val) < 0)
+            val = 0;
         break;
     }
     EAX = (uint32_t)(val);
diff --git a/vl.c b/vl.c
index c0e43ac..42720e8 100644
--- a/vl.c
+++ b/vl.c
@@ -140,6 +140,7 @@
 #include "disas.h"
 
 #include "exec-all.h"
+#include "accel.h"
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
@@ -149,6 +150,8 @@
 #define SMBD_COMMAND "/usr/sbin/smbd"
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_UNUSED_IOPORT
 //#define DEBUG_IOPORT
 //#define DEBUG_NET
@@ -252,6 +255,14 @@ static QEMUTimer *icount_vm_timer;
 
 uint8_t qemu_uuid[16];
 
+QEMUAccel *available_accels[] = {
+/* list of available accelerators */
+#ifdef USE_KQEMU
+    &kqemu_accel,
+    &kqemu_kernel_accel,
+#endif
+};
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /***********************************************************/
@@ -410,10 +421,7 @@ void cpu_outb(CPUState *env, int addr, int val)
         fprintf(logfile, "outb: %04x %02x\n", addr, val);
 #endif
     ioport_write(0, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outw(CPUState *env, int addr, int val)
@@ -423,10 +431,7 @@ void cpu_outw(CPUState *env, int addr, int val)
         fprintf(logfile, "outw: %04x %04x\n", addr, val);
 #endif
     ioport_write(1, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outl(CPUState *env, int addr, int val)
@@ -436,10 +441,7 @@ void cpu_outl(CPUState *env, int addr, int val)
         fprintf(logfile, "outl: %04x %08x\n", addr, val);
 #endif
     ioport_write(2, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 int cpu_inb(CPUState *env, int addr)
@@ -450,10 +452,7 @@ int cpu_inb(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inb : %04x %02x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -465,10 +464,7 @@ int cpu_inw(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inw : %04x %04x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -480,10 +476,7 @@ int cpu_inl(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inl : %04x %08x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -1317,11 +1310,6 @@ static void host_alarm_handler(int host_signum)
         if (env) {
             /* stop the currently executing cpu because a timer occured */
             cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-            if (env->kqemu_enabled) {
-                kqemu_cpu_interrupt(env);
-            }
-#endif
         }
         event_pending = 1;
     }
@@ -7560,14 +7548,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
 void qemu_service_io(void)
 {
     CPUState *env = cpu_single_env;
-    if (env) {
+    if (env)
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
-        }
-#endif
-    }
 }
 
 /***********************************************************/
@@ -8255,10 +8237,6 @@ static void help(int exitcode)
            "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
            "                translation (t=none or lba) (usually qemu can guess them)\n"
            "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
-#ifdef USE_KQEMU
-           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
-           "-no-kqemu       disable KQEMU kernel module usage\n"
-#endif
 #ifdef TARGET_I386
            "-no-acpi        disable ACPI\n"
 #endif
@@ -8362,8 +8340,7 @@ enum {
     QEMU_OPTION_alt_grab,
     QEMU_OPTION_no_quit,
     QEMU_OPTION_pidfile,
-    QEMU_OPTION_no_kqemu,
-    QEMU_OPTION_kernel_kqemu,
+    QEMU_OPTION_accel,
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
@@ -8446,10 +8423,7 @@ static const QEMUOption qemu_options[] = {
     { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
     { "L", HAS_ARG, QEMU_OPTION_L },
     { "bios", HAS_ARG, QEMU_OPTION_bios },
-#ifdef USE_KQEMU
-    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
-    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-#endif
+    { "accel", HAS_ARG, QEMU_OPTION_accel},
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
 #endif
@@ -9264,14 +9238,15 @@ int main(int argc, char **argv)
                 win2k_install_hack = 1;
                 break;
 #endif
-#ifdef USE_KQEMU
-            case QEMU_OPTION_no_kqemu:
-                kqemu_allowed = 0;
-                break;
-            case QEMU_OPTION_kernel_kqemu:
-                kqemu_allowed = 2;
+            case QEMU_OPTION_accel:
+                {
+                    int i;
+                    for (i = 0; i < ARRAY_SIZE(available_accels); i++) {
+                        if (!strcasecmp(optarg, available_accels[i]->name))
+                            register_qemu_accel(available_accels[i]);
+                    }
+                }
                 break;
-#endif
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
                 break;
@@ -9413,6 +9388,9 @@ int main(int argc, char **argv)
         exit(1);
     }
 
+    /* Basic handler for the noaccel case */
+    register_qemu_accel(&noaccel);
+
     if (nographic) {
        if (serial_device_index == 0)
            serial_devices[0] = "stdio";
@@ -9476,10 +9454,6 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-#ifdef USE_KQEMU
-    if (smp_cpus > 1)
-        kqemu_allowed = 0;
-#endif
     linux_boot = (kernel_filename != NULL);
     net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
 
@@ -9600,6 +9574,11 @@ int main(int argc, char **argv)
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
 
+    if (accel_start(smp_cpus)) {
+	    fprintf(stderr, "qemu: error, no suitable accelerator found\n");
+	    exit(1);
+    }
+
     bdrv_init();
 
     /* we always create the cdrom drive, even if no disk is there */

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
  2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
  2008-10-23 13:44 ` Anthony Liguori
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:35   ` [Qemu-devel] " Jan Kiszka
  2008-10-23 13:48   ` Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion Glauber Costa
                   ` (30 subsequent siblings)
  33 siblings, 2 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 osdep.c |  111 ---------------------------------------------------------------
 1 files changed, 0 insertions(+), 111 deletions(-)

diff --git a/osdep.c b/osdep.c
index 683aad0..31c96e6 100644
--- a/osdep.c
+++ b/osdep.c
@@ -68,112 +68,9 @@ void qemu_vfree(void *ptr)
 
 #else
 
-#if defined(USE_KQEMU)
-
-#ifdef __OpenBSD__
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/mount.h>
-#else
-#include <sys/vfs.h>
-#endif
-
 #include <sys/mman.h>
 #include <fcntl.h>
 
-static void *kqemu_vmalloc(size_t size)
-{
-    static int phys_ram_fd = -1;
-    static int phys_ram_size = 0;
-    void *ptr;
-
-#ifdef __OpenBSD__ /* no need (?) for a dummy file on OpenBSD */
-    int map_anon = MAP_ANON;
-#else
-    int map_anon = 0;
-    const char *tmpdir;
-    char phys_ram_file[1024];
-#ifdef HOST_SOLARIS
-    struct statvfs stfs;
-#else
-    struct statfs stfs;
-#endif
-
-    if (phys_ram_fd < 0) {
-        tmpdir = getenv("QEMU_TMPDIR");
-        if (!tmpdir)
-#ifdef HOST_SOLARIS
-            tmpdir = "/tmp";
-        if (statvfs(tmpdir, &stfs) == 0) {
-#else
-            tmpdir = "/dev/shm";
-        if (statfs(tmpdir, &stfs) == 0) {
-#endif
-            int64_t free_space;
-            int ram_mb;
-
-            free_space = (int64_t)stfs.f_bavail * stfs.f_bsize;
-            if ((ram_size + 8192 * 1024) >= free_space) {
-                ram_mb = (ram_size / (1024 * 1024));
-                fprintf(stderr,
-                        "You do not have enough space in '%s' for the %d MB of QEMU virtual RAM.\n",
-                        tmpdir, ram_mb);
-                if (strcmp(tmpdir, "/dev/shm") == 0) {
-                    fprintf(stderr, "To have more space available provided you have enough RAM and swap, do as root:\n"
-                            "mount -o remount,size=%dm /dev/shm\n",
-                            ram_mb + 16);
-                } else {
-                    fprintf(stderr,
-                            "Use the '-m' option of QEMU to diminish the amount of virtual RAM or use the\n"
-                            "QEMU_TMPDIR environment variable to set another directory where the QEMU\n"
-                            "temporary RAM file will be opened.\n");
-                }
-                fprintf(stderr, "Or disable the accelerator module with -no-kqemu\n");
-                exit(1);
-            }
-        }
-        snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                 tmpdir);
-        phys_ram_fd = mkstemp(phys_ram_file);
-        if (phys_ram_fd < 0) {
-            fprintf(stderr,
-                    "warning: could not create temporary file in '%s'.\n"
-                    "Use QEMU_TMPDIR to select a directory in a tmpfs filesystem.\n"
-                    "Using '/tmp' as fallback.\n",
-                    tmpdir);
-            snprintf(phys_ram_file, sizeof(phys_ram_file), "%s/qemuXXXXXX",
-                     "/tmp");
-            phys_ram_fd = mkstemp(phys_ram_file);
-            if (phys_ram_fd < 0) {
-                fprintf(stderr, "Could not create temporary memory file '%s'\n",
-                        phys_ram_file);
-                exit(1);
-            }
-        }
-        unlink(phys_ram_file);
-    }
-    size = (size + 4095) & ~4095;
-    ftruncate(phys_ram_fd, phys_ram_size + size);
-#endif /* !__OpenBSD__ */
-    ptr = mmap(NULL,
-               size,
-               PROT_WRITE | PROT_READ, map_anon | MAP_SHARED,
-               phys_ram_fd, phys_ram_size);
-    if (ptr == MAP_FAILED) {
-        fprintf(stderr, "Could not map physical memory\n");
-        exit(1);
-    }
-    phys_ram_size += size;
-    return ptr;
-}
-
-static void kqemu_vfree(void *ptr)
-{
-    /* may be useful some day, but currently we do not need to free */
-}
-
-#endif
-
 void *qemu_memalign(size_t alignment, size_t size)
 {
 #if defined(_POSIX_C_SOURCE)
@@ -193,10 +90,6 @@ void *qemu_memalign(size_t alignment, size_t size)
 /* alloc shared memory pages */
 void *qemu_vmalloc(size_t size)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        return kqemu_vmalloc(size);
-#endif
 #ifdef _BSD
     return valloc(size);
 #else
@@ -206,10 +99,6 @@ void *qemu_vmalloc(size_t size)
 
 void qemu_vfree(void *ptr)
 {
-#if defined(USE_KQEMU)
-    if (kqemu_allowed)
-        kqemu_vfree(ptr);
-#endif
     free(ptr);
 }
 
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (2 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 03/32] change definition of FILE for linux Glauber Costa
                   ` (29 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 exec-all.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 6609c9a..e3da98a 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -18,6 +18,8 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifndef _EXEC_ALL_H_
+#define _EXEC_ALL_H_
 /* allow to see translation results - the slowdown should be negligible, so we leave it */
 #define DEBUG_DISAS
 
@@ -385,3 +387,4 @@ static inline int kqemu_is_ok(CPUState *env)
 }
 
 #endif
+#endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 03/32] change definition of FILE for linux
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (3 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c Glauber Costa
                   ` (28 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

use _IO_FILE, as it seems to be the case.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 dyngen-exec.h |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/dyngen-exec.h b/dyngen-exec.h
index 9260b6f..826ff46 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -27,6 +27,10 @@
 #define _FILEDEFED
 #endif
 
+#ifdef __linux__
+#define __FILE_defined
+#endif
+
 /* NOTE: standard headers should be used with special care at this
    point because host CPU registers are used as global variables. Some
    host headers do not allow that. */
@@ -84,6 +88,8 @@ typedef void * host_reg_t;
 
 #ifdef _BSD
 typedef struct __sFILE FILE;
+#elif defined(__linux__)
+typedef struct _IO_FILE FILE;
 #else
 typedef struct FILE FILE;
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (4 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 03/32] change definition of FILE for linux Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:55   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec Glauber Costa
                   ` (27 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Only pieces of code that are frame-safe can be moved.
compute_all() is an example of a non-frame-safe calling.
So it has to be done prior to calling kqemu_cpu_exec().

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 cpu-exec.c |   33 +++++++++++++--------------------
 kqemu.c    |   18 +++++++++++++++++-
 2 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 6d4dcdd..f06df26 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -336,27 +336,20 @@ int cpu_exec(CPUState *env1)
                 env->exception_index = -1;
             }
 #ifdef USE_KQEMU
-            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
-                int ret;
-                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
-                ret = kqemu_cpu_exec(env);
-                /* put eflags in CPU temporary format */
-                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                DF = 1 - (2 * ((env->eflags >> 10) & 1));
-                CC_OP = CC_OP_EFLAGS;
-                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-                if (ret == 1) {
-                    /* exception */
-                    longjmp(env->jmp_env, 1);
-                } else if (ret == 2) {
-                    /* softmmu execution needed */
+            env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
+            ret = kqemu_cpu_exec(env);
+            env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+            if (ret == 1) {
+                /* exception */
+                longjmp(env->jmp_env, 1);
+            } else if (ret == 2) {
+                /* softmmu execution needed */
+            } else {
+                if (env->interrupt_request != 0) {
+                    /* hardware interrupt will be executed just after */
                 } else {
-                    if (env->interrupt_request != 0) {
-                        /* hardware interrupt will be executed just after */
-                    } else {
-                        /* otherwise, we restart */
-                        longjmp(env->jmp_env, 1);
-                    }
+                    /* otherwise, we restart */
+                    longjmp(env->jmp_env, 1);
                 }
             }
 #endif
diff --git a/kqemu.c b/kqemu.c
index 4783aa2..39938e0 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -30,6 +30,7 @@
 #ifdef HOST_SOLARIS
 #include <sys/ioccom.h>
 #endif
+#include "exec.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
@@ -689,7 +690,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
     sc->base = ksc->base;
 }
 
-int kqemu_cpu_exec(CPUState *env)
+int kqemu_do_cpu_exec(CPUState *env)
 {
     struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
     int ret, cpl, i;
@@ -939,6 +940,21 @@ int kqemu_cpu_exec(CPUState *env)
     return 0;
 }
 
+int kqemu_cpu_exec(CPUState *env)
+{
+
+    int ret = 2;
+    if (kqemu_is_ok(env) && env->interrupt_request == 0) {
+        ret = kqemu_do_cpu_exec(env);
+        /* put eflags in CPU temporary format */
+        CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+        DF = 1 - (2 * ((env->eflags >> 10) & 1));
+        CC_OP = CC_OP_EFLAGS;
+    }
+    return ret;
+}
+
+
 void kqemu_cpu_interrupt(CPUState *env)
 {
 #if defined(_WIN32)
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (5 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:57   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 06/32] split kqemu_init into two Glauber Costa
                   ` (26 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

define constants that actually mean something instead of 1, 2, etc

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 cpu-exec.c |    4 ++--
 exec-all.h |    4 ++++
 kqemu.c    |   12 ++++++------
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index f06df26..88b7d6f 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -339,10 +339,10 @@ int cpu_exec(CPUState *env1)
             env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
             ret = kqemu_cpu_exec(env);
             env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-            if (ret == 1) {
+            if (ret == EXEC_EXIT_INTR) {
                 /* exception */
                 longjmp(env->jmp_env, 1);
-            } else if (ret == 2) {
+            } else if (ret == EXEC_EXIT_SOFTMMU) {
                 /* softmmu execution needed */
             } else {
                 if (env->interrupt_request != 0) {
diff --git a/exec-all.h b/exec-all.h
index e3da98a..c10248b 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -356,6 +356,10 @@ static inline int can_do_io(CPUState *env)
 }
 #endif
 
+#define EXEC_EXIT_DONE 0
+#define EXEC_EXIT_INTR 1
+#define EXEC_EXIT_SOFTMMU 2
+
 #ifdef USE_KQEMU
 #define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
 
diff --git a/kqemu.c b/kqemu.c
index 39938e0..d2bfd05 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -892,7 +892,7 @@ int kqemu_do_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if ((ret & 0xff00) == KQEMU_RET_EXCEPTION) {
         env->exception_index = ret & 0xff;
         env->error_code = kenv->error_code;
@@ -908,7 +908,7 @@ int kqemu_do_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 1;
+        return EXEC_EXIT_INTR;
     } else if (ret == KQEMU_RET_INTR) {
 #ifdef CONFIG_PROFILER
         kqemu_ret_intr_count++;
@@ -918,7 +918,7 @@ int kqemu_do_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 0;
+        return EXEC_EXIT_DONE;
     } else if (ret == KQEMU_RET_SOFTMMU) {
 #ifdef CONFIG_PROFILER
         {
@@ -931,19 +931,19 @@ int kqemu_do_cpu_exec(CPUState *env)
             cpu_dump_state(env, logfile, fprintf, 0);
         }
 #endif
-        return 2;
+        return EXEC_EXIT_SOFTMMU;
     } else {
         cpu_dump_state(env, stderr, fprintf, 0);
         fprintf(stderr, "Unsupported return value: 0x%x\n", ret);
         exit(1);
     }
-    return 0;
+    return EXEC_EXIT_DONE;
 }
 
 int kqemu_cpu_exec(CPUState *env)
 {
 
-    int ret = 2;
+    int ret = EXEC_EXIT_SOFTMMU;
     if (kqemu_is_ok(env) && env->interrupt_request == 0) {
         ret = kqemu_do_cpu_exec(env);
         /* put eflags in CPU temporary format */
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 06/32] split kqemu_init into two
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (6 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 13:58   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver Glauber Costa
                   ` (25 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

we separate kqemu_init() into a part that depends on env,
and other that does not. The later can be initialized earlier

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@siemens.com>
---
 exec-all.h           |    1 -
 exec.c               |    5 ++++-
 kqemu.c              |   10 +++++++---
 target-i386/helper.c |    2 +-
 4 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index c10248b..9ea9b4e 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -365,7 +365,6 @@ static inline int can_do_io(CPUState *env)
 
 #define MSR_QPI_COMMBASE 0xfabe0010
 
-int kqemu_init(CPUState *env);
 int kqemu_cpu_exec(CPUState *env);
 void kqemu_flush_page(CPUState *env, target_ulong addr);
 void kqemu_flush(CPUState *env, int global);
diff --git a/exec.c b/exec.c
index f1fcec8..1cad0be 100644
--- a/exec.c
+++ b/exec.c
@@ -495,6 +495,9 @@ void cpu_exec_init_all(unsigned long tb_size)
 #if !defined(CONFIG_USER_ONLY)
     io_mem_init();
 #endif
+#ifdef USE_KQEMU
+    kqemu_start();
+#endif
 }
 
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
@@ -2207,7 +2210,7 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
 #ifdef USE_KQEMU
     /* XXX: should not depend on cpu context */
     env = first_cpu;
-    if (env->kqemu_enabled) {
+    if (env && env->kqemu_enabled) {
         kqemu_set_phys_mem(start_addr, size, phys_offset);
     }
 #endif
diff --git a/kqemu.c b/kqemu.c
index d2bfd05..11f8c8a 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -151,7 +151,7 @@ static void kqemu_update_cpuid(CPUState *env)
        accelerated code */
 }
 
-int kqemu_init(CPUState *env)
+int kqemu_start(void)
 {
     struct kqemu_init kinit;
     int ret, version;
@@ -231,8 +231,6 @@ int kqemu_init(CPUState *env)
         kqemu_fd = KQEMU_INVALID_FD;
         return -1;
     }
-    kqemu_update_cpuid(env);
-    env->kqemu_enabled = kqemu_allowed;
     nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;
 
@@ -240,6 +238,12 @@ int kqemu_init(CPUState *env)
     return 0;
 }
 
+void kqemu_init_env(CPUState *env)
+{
+    kqemu_update_cpuid(env);
+    env->kqemu_enabled = kqemu_allowed;
+}
+
 void kqemu_flush_page(CPUState *env, target_ulong addr)
 {
 #if defined(DEBUG)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index c2e1a88..b36e391 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -113,7 +113,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     }
     cpu_reset(env);
 #ifdef USE_KQEMU
-    kqemu_init(env);
+    kqemu_init_env(env);
 #endif
     return env;
 }
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (7 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 06/32] split kqemu_init into two Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:00   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 08/32] init env made accel driver Glauber Costa
                   ` (24 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

This patch introduces QEMUAccel, a placeholder for function pointers
that aims at helping qemu to abstract accelerators such as kqemu and
kvm (actually, the 'accelerator' name was proposed by avi kivity, since
he loves referring to kvm that way).

To begin with, the accelerator is given the opportunity to register a
cpu_interrupt function, to be called after the raw cpu_interrupt.
This has the side effect of, for the kqemu accelerator, calling kqemu_cpu_interrupt
everytime, which didn't use to happen. But looking at the code, this seems safe to me.

This patch applies on raw qemu.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@siemens.com>
---
 Makefile.target |    2 +-
 accel.c         |   17 +++++++++++++++++
 accel.h         |   20 ++++++++++++++++++++
 exec-all.h      |    1 -
 exec.c          |    3 +++
 kqemu.c         |   11 ++++++++++-
 vl.c            |   17 +++++------------
 7 files changed, 56 insertions(+), 15 deletions(-)
 create mode 100644 accel.c
 create mode 100644 accel.h

diff --git a/Makefile.target b/Makefile.target
index e2edf9d..623ecd8 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -188,7 +188,7 @@ all: $(PROGS)
 #########################################################
 # cpu emulator library
 LIBOBJS=exec.o kqemu.o translate-all.o cpu-exec.o\
-        translate.o host-utils.o
+        translate.o host-utils.o accel.o
 ifdef CONFIG_DYNGEN_OP
 exec.o: dyngen-opc.h
 LIBOBJS+=op.o
diff --git a/accel.c b/accel.c
new file mode 100644
index 0000000..d30460d
--- /dev/null
+++ b/accel.c
@@ -0,0 +1,17 @@
+#include "hw/hw.h"
+#include "accel.h"
+
+QEMUAccel *current_accel;
+
+int _accel_nop(void)
+{
+    return 0;
+}
+
+#define accel_nop ((void *)_accel_nop)
+
+/* Accelerator wrapper for the no-accel (raw qemu) case */
+QEMUAccel noaccel = {
+    .cpu_interrupt = accel_nop,
+};
+
diff --git a/accel.h b/accel.h
new file mode 100644
index 0000000..8e5ddc6
--- /dev/null
+++ b/accel.h
@@ -0,0 +1,20 @@
+#ifndef _ACCEL_H_
+#define _ACCEL_H_
+
+typedef struct QEMUAccel {
+    void (*cpu_interrupt)(CPUState *env);
+} QEMUAccel;
+
+extern QEMUAccel *current_accel;
+extern QEMUAccel noaccel;
+
+static inline void register_qemu_accel(QEMUAccel *accel)
+{
+    current_accel = accel;
+}
+
+static inline void accel_cpu_interrupt(CPUState *env)
+{
+    current_accel->cpu_interrupt(env);
+}
+#endif
diff --git a/exec-all.h b/exec-all.h
index 9ea9b4e..0a84f58 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -372,7 +372,6 @@ void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
 void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
                         ram_addr_t phys_offset);
-void kqemu_cpu_interrupt(CPUState *env);
 void kqemu_record_dump(void);
 
 extern uint32_t kqemu_comm_base;
diff --git a/exec.c b/exec.c
index 1cad0be..21253cc 100644
--- a/exec.c
+++ b/exec.c
@@ -43,6 +43,8 @@
 #include <qemu.h>
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
 //#define DEBUG_TLB
@@ -1430,6 +1432,7 @@ void cpu_single_step(CPUState *env, int enabled)
         tb_flush(env);
     }
 #endif
+    accel_cpu_interrupt(env);
 }
 
 /* enable or disable low levels log */
diff --git a/kqemu.c b/kqemu.c
index 11f8c8a..dc989a3 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -51,6 +51,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include "kqemu.h"
+#include "accel.h"
 
 #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"
@@ -151,6 +152,8 @@ static void kqemu_update_cpuid(CPUState *env)
        accelerated code */
 }
 
+QEMUAccel kqemu_accel;
+
 int kqemu_start(void)
 {
     struct kqemu_init kinit;
@@ -233,6 +236,7 @@ int kqemu_start(void)
     }
     nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;
+    register_qemu_accel(&kqemu_accel);
 
     qpi_init();
     return 0;
@@ -959,7 +963,7 @@ int kqemu_cpu_exec(CPUState *env)
 }
 
 
-void kqemu_cpu_interrupt(CPUState *env)
+static void kqemu_cpu_interrupt(CPUState *env)
 {
 #if defined(_WIN32)
     /* cancelling the I/O request causes KQEMU to finish executing the
@@ -1042,4 +1046,9 @@ static void qpi_init(void)
     cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
                                  0x1000, qpi_io_memory);
 }
+
+QEMUAccel kqemu_accel = {
+    .cpu_interrupt = kqemu_cpu_interrupt,
+};
+
 #endif
diff --git a/vl.c b/vl.c
index c0e43ac..adf5b25 100644
--- a/vl.c
+++ b/vl.c
@@ -149,6 +149,8 @@
 #define SMBD_COMMAND "/usr/sbin/smbd"
 #endif
 
+#include "accel.h"
+
 //#define DEBUG_UNUSED_IOPORT
 //#define DEBUG_IOPORT
 //#define DEBUG_NET
@@ -1317,11 +1319,6 @@ static void host_alarm_handler(int host_signum)
         if (env) {
             /* stop the currently executing cpu because a timer occured */
             cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-            if (env->kqemu_enabled) {
-                kqemu_cpu_interrupt(env);
-            }
-#endif
         }
         event_pending = 1;
     }
@@ -7560,14 +7557,8 @@ static int ram_load(QEMUFile *f, void *opaque, int version_id)
 void qemu_service_io(void)
 {
     CPUState *env = cpu_single_env;
-    if (env) {
+    if (env)
         cpu_interrupt(env, CPU_INTERRUPT_EXIT);
-#ifdef USE_KQEMU
-        if (env->kqemu_enabled) {
-            kqemu_cpu_interrupt(env);
-        }
-#endif
-    }
 }
 
 /***********************************************************/
@@ -8824,6 +8815,8 @@ int main(int argc, char **argv)
     }
 #endif
 
+    register_qemu_accel(&noaccel);
+
     register_machines();
     machine = first_machine;
     cpu_model = NULL;
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 08/32] init env made accel driver
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (8 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 09/32] wrap cache flushing functions into accel drivers Glauber Costa
                   ` (23 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: init_env
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c              |    1 +
 accel.h              |    7 +++++++
 kqemu.c              |    3 ++-
 target-i386/helper.c |    6 +++---
 4 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/accel.c b/accel.c
index d30460d..3a17dc5 100644
--- a/accel.c
+++ b/accel.c
@@ -13,5 +13,6 @@ int _accel_nop(void)
 /* Accelerator wrapper for the no-accel (raw qemu) case */
 QEMUAccel noaccel = {
     .cpu_interrupt = accel_nop,
+    .init_env = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index 8e5ddc6..0d916dc 100644
--- a/accel.h
+++ b/accel.h
@@ -3,6 +3,7 @@
 
 typedef struct QEMUAccel {
     void (*cpu_interrupt)(CPUState *env);
+    void (*init_env)(CPUState *env);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -17,4 +18,10 @@ static inline void accel_cpu_interrupt(CPUState *env)
 {
     current_accel->cpu_interrupt(env);
 }
+
+static inline void accel_init_env(CPUState *env)
+{
+    current_accel->init_env(env);
+}
+
 #endif
diff --git a/kqemu.c b/kqemu.c
index dc989a3..8c228f4 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -242,7 +242,7 @@ int kqemu_start(void)
     return 0;
 }
 
-void kqemu_init_env(CPUState *env)
+static void kqemu_init_env(CPUState *env)
 {
     kqemu_update_cpuid(env);
     env->kqemu_enabled = kqemu_allowed;
@@ -1049,6 +1049,7 @@ static void qpi_init(void)
 
 QEMUAccel kqemu_accel = {
     .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env,
 };
 
 #endif
diff --git a/target-i386/helper.c b/target-i386/helper.c
index b36e391..b981b92 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -30,6 +30,8 @@
 #include "svm.h"
 #include "qemu-common.h"
 
+#include "accel.h"
+
 //#define DEBUG_MMU
 
 static int cpu_x86_register (CPUX86State *env, const char *cpu_model);
@@ -112,9 +114,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
         return NULL;
     }
     cpu_reset(env);
-#ifdef USE_KQEMU
-    kqemu_init_env(env);
-#endif
+    accel_init_env(env);
     return env;
 }
 
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 09/32] wrap cache flushing functions into accel drivers
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (9 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 08/32] init env made accel driver Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator Glauber Costa
                   ` (22 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: cache flushing functions
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c    |    2 ++
 accel.h    |   11 +++++++++++
 exec-all.h |    2 --
 exec.c     |   13 +++----------
 kqemu.c    |    6 ++++--
 5 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/accel.c b/accel.c
index 3a17dc5..6776244 100644
--- a/accel.c
+++ b/accel.c
@@ -14,5 +14,7 @@ int _accel_nop(void)
 QEMUAccel noaccel = {
     .cpu_interrupt = accel_nop,
     .init_env = accel_nop,
+    .flush_cache = accel_nop,
+    .flush_page = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index 0d916dc..935cfef 100644
--- a/accel.h
+++ b/accel.h
@@ -4,6 +4,8 @@
 typedef struct QEMUAccel {
     void (*cpu_interrupt)(CPUState *env);
     void (*init_env)(CPUState *env);
+    void (*flush_cache)(CPUState *env, int global);
+    void (*flush_page)(CPUState *env, target_ulong addr);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -24,4 +26,13 @@ static inline void accel_init_env(CPUState *env)
     current_accel->init_env(env);
 }
 
+static inline void accel_flush_cache(CPUState *env, int global)
+{
+    current_accel->flush_cache(env, global);
+}
+
+static inline void accel_flush_page(CPUState *env, target_ulong addr)
+{
+    current_accel->flush_page(env, addr);
+}
 #endif
diff --git a/exec-all.h b/exec-all.h
index 0a84f58..2098fe8 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -366,8 +366,6 @@ static inline int can_do_io(CPUState *env)
 #define MSR_QPI_COMMBASE 0xfabe0010
 
 int kqemu_cpu_exec(CPUState *env);
-void kqemu_flush_page(CPUState *env, target_ulong addr);
-void kqemu_flush(CPUState *env, int global);
 void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
 void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
diff --git a/exec.c b/exec.c
index 21253cc..4f7aa67 100644
--- a/exec.c
+++ b/exec.c
@@ -1684,11 +1684,8 @@ void tlb_flush(CPUState *env, int flush_global)
 
     memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush(env, flush_global);
-    }
-#endif
+    accel_flush_cache(env, flush_global);
+
     tlb_flush_count++;
 }
 
@@ -1730,11 +1727,7 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
 
     tlb_flush_jmp_cache(env, addr);
 
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        kqemu_flush_page(env, addr);
-    }
-#endif
+    accel_flush_page(env, addr);
 }
 
 /* update the TLBs so that writes to code in the virtual page 'addr'
diff --git a/kqemu.c b/kqemu.c
index 8c228f4..3f2433a 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -248,7 +248,7 @@ static void kqemu_init_env(CPUState *env)
     env->kqemu_enabled = kqemu_allowed;
 }
 
-void kqemu_flush_page(CPUState *env, target_ulong addr)
+static void kqemu_flush_page(CPUState *env, target_ulong addr)
 {
 #if defined(DEBUG)
     if (loglevel & CPU_LOG_INT) {
@@ -261,7 +261,7 @@ void kqemu_flush_page(CPUState *env, target_ulong addr)
         pages_to_flush[nb_pages_to_flush++] = addr;
 }
 
-void kqemu_flush(CPUState *env, int global)
+static void kqemu_flush(CPUState *env, int global)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -1050,6 +1050,8 @@ static void qpi_init(void)
 QEMUAccel kqemu_accel = {
     .cpu_interrupt = kqemu_cpu_interrupt,
     .init_env = kqemu_init_env,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (10 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 09/32] wrap cache flushing functions into accel drivers Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:03   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 11/32] separate accelerator part of info profiler Glauber Costa
                   ` (21 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: info.
>From this point on, "info kqemu" is no more. "info accelerator" should
be used instead.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c   |    6 ++++++
 accel.h   |    8 ++++++++
 kqemu.c   |   26 ++++++++++++++++++++++++++
 monitor.c |   35 ++++++++++++-----------------------
 4 files changed, 52 insertions(+), 23 deletions(-)

diff --git a/accel.c b/accel.c
index 6776244..cb615d7 100644
--- a/accel.c
+++ b/accel.c
@@ -8,6 +8,11 @@ int _accel_nop(void)
     return 0;
 }
 
+int noaccel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
+}
+
 #define accel_nop ((void *)_accel_nop)
 
 /* Accelerator wrapper for the no-accel (raw qemu) case */
@@ -16,5 +21,6 @@ QEMUAccel noaccel = {
     .init_env = accel_nop,
     .flush_cache = accel_nop,
     .flush_page = accel_nop,
+    .info = noaccel_info,
 };
 
diff --git a/accel.h b/accel.h
index 935cfef..549ce01 100644
--- a/accel.h
+++ b/accel.h
@@ -1,11 +1,14 @@
 #ifndef _ACCEL_H_
 #define _ACCEL_H_
 
+#define MAX_INFO_BUF 1024
+
 typedef struct QEMUAccel {
     void (*cpu_interrupt)(CPUState *env);
     void (*init_env)(CPUState *env);
     void (*flush_cache)(CPUState *env, int global);
     void (*flush_page)(CPUState *env, target_ulong addr);
+    int (*info)(CPUState *env, char *buf);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -35,4 +38,9 @@ static inline void accel_flush_page(CPUState *env, target_ulong addr)
 {
     current_accel->flush_page(env, addr);
 }
+
+static inline int accel_info(CPUState *env, char *buf)
+{
+    return current_accel->info(env, buf);
+}
 #endif
diff --git a/kqemu.c b/kqemu.c
index 3f2433a..424d8f4 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1047,11 +1047,37 @@ static void qpi_init(void)
                                  0x1000, qpi_io_memory);
 }
 
+static int kqemu_info(CPUState *env, char *buf)
+{
+    int val, len;
+    int bufsiz = MAX_INFO_BUF;
+    val = 0;
+    val = env->kqemu_enabled;
+    len = snprintf(buf, bufsiz, "kqemu support: ");
+    buf += len;
+    bufsiz -= len;
+
+    switch(val) {
+    default:
+        len += snprintf(buf, bufsiz, "present, but bogus value\n");
+        break;
+    case 1:
+        len += snprintf(buf, bufsiz, "enabled for user code\n");
+        break;
+    case 2:
+        len += snprintf(buf, bufsiz, "enabled for user and kernel code\n");
+        break;
+    }
+
+    return len;
+}
+
 QEMUAccel kqemu_accel = {
     .cpu_interrupt = kqemu_cpu_interrupt,
     .init_env = kqemu_init_env,
     .flush_cache = kqemu_flush,
     .flush_page = kqemu_flush_page,
+    .info = kqemu_info,
 };
 
 #endif
diff --git a/monitor.c b/monitor.c
index f0a0bc3..d3ab137 100644
--- a/monitor.c
+++ b/monitor.c
@@ -34,6 +34,7 @@
 #include "block.h"
 #include "audio/audio.h"
 #include "disas.h"
+#include "accel.h"
 #include <dirent.h>
 #include "qemu-timer.h"
 #include "migration.h"
@@ -1233,34 +1234,22 @@ static void mem_info(void)
 }
 #endif
 
-static void do_info_kqemu(void)
+static void do_info_accelerator(void)
 {
-#ifdef USE_KQEMU
+    char buf[MAX_INFO_BUF];
     CPUState *env;
-    int val;
-    val = 0;
+
     env = mon_get_cpu();
+
     if (!env) {
         term_printf("No cpu initialized yet");
         return;
     }
-    val = env->kqemu_enabled;
-    term_printf("kqemu support: ");
-    switch(val) {
-    default:
-    case 0:
-        term_printf("disabled\n");
-        break;
-    case 1:
-        term_printf("enabled for user code\n");
-        break;
-    case 2:
-        term_printf("enabled for user and kernel code\n");
-        break;
-    }
-#else
-    term_printf("kqemu support: not compiled\n");
-#endif
+
+    if (accel_info(env, buf))
+        term_printf(buf);
+    else
+        term_printf("No accelerator present\n");
 }
 
 #ifdef CONFIG_PROFILER
@@ -1493,8 +1482,8 @@ static const term_cmd_t info_cmds[] = {
 #endif
     { "jit", "", do_info_jit,
       "", "show dynamic compiler info", },
-    { "kqemu", "", do_info_kqemu,
-      "", "show kqemu information", },
+    { "accelerator", "", do_info_accelerator,
+      "", "show accelerator information", },
     { "usb", "", usb_info,
       "", "show guest USB devices", },
     { "usbhost", "", usb_host_info,
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 11/32] separate accelerator part of info profiler
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (11 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 12/32] move kqemu externs to kqemu.h Glauber Costa
                   ` (20 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: profile.
It allows the accelerators to do part of the profiling their own way.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c   |    1 +
 accel.h   |    6 ++++++
 kqemu.c   |   35 +++++++++++++++++++++++++++++++++++
 monitor.c |   27 ++++++---------------------
 4 files changed, 48 insertions(+), 21 deletions(-)

diff --git a/accel.c b/accel.c
index cb615d7..40dfac6 100644
--- a/accel.c
+++ b/accel.c
@@ -22,5 +22,6 @@ QEMUAccel noaccel = {
     .flush_cache = accel_nop,
     .flush_page = accel_nop,
     .info = noaccel_info,
+    .profile = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index 549ce01..bb56526 100644
--- a/accel.h
+++ b/accel.h
@@ -9,6 +9,7 @@ typedef struct QEMUAccel {
     void (*flush_cache)(CPUState *env, int global);
     void (*flush_page)(CPUState *env, target_ulong addr);
     int (*info)(CPUState *env, char *buf);
+    int (*profile)(CPUState *env, char *buf);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -43,4 +44,9 @@ static inline int accel_info(CPUState *env, char *buf)
 {
     return current_accel->info(env, buf);
 }
+
+static inline int accel_profile(CPUState *env, char *buf)
+{
+   return current_accel->profile(env, buf);
+}
 #endif
diff --git a/kqemu.c b/kqemu.c
index 424d8f4..0a1d63b 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -53,6 +53,10 @@
 #include "kqemu.h"
 #include "accel.h"
 
+#ifdef CONFIG_PROFILER
+#include "qemu-timer.h" /* for ticks_per_sec */
+#endif
+
 #ifdef _WIN32
 #define KQEMU_DEVICE "\\\\.\\kqemu"
 #else
@@ -1072,12 +1076,43 @@ static int kqemu_info(CPUState *env, char *buf)
     return len;
 }
 
+int64_t kqemu_time;
+int64_t kqemu_exec_count;
+int64_t kqemu_ret_int_count;
+int64_t kqemu_ret_excp_count;
+int64_t kqemu_ret_intr_count;
+extern int64_t qemu_time;
+
+static int kqemu_profile(CPUState *env, char *buf)
+{
+    int len = 0;
+#ifdef CONFIG_PROFILER
+    len = sprintf(buf, "kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64
+                        " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
+                kqemu_time, kqemu_time / (double)ticks_per_sec,
+                kqemu_time / qemu_time * 100.0,
+                kqemu_exec_count,
+                kqemu_ret_int_count,
+                kqemu_ret_excp_count,
+                kqemu_ret_intr_count);
+
+    kqemu_time = 0;
+    kqemu_exec_count = 0;
+    kqemu_ret_int_count = 0;
+    kqemu_ret_excp_count = 0;
+    kqemu_ret_intr_count = 0;
+    kqemu_record_dump();
+#endif
+    return len;
+}
+
 QEMUAccel kqemu_accel = {
     .cpu_interrupt = kqemu_cpu_interrupt,
     .init_env = kqemu_init_env,
     .flush_cache = kqemu_flush,
     .flush_page = kqemu_flush_page,
     .info = kqemu_info,
+    .profile = kqemu_profile,
 };
 
 #endif
diff --git a/monitor.c b/monitor.c
index d3ab137..42a1b02 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1254,17 +1254,14 @@ static void do_info_accelerator(void)
 
 #ifdef CONFIG_PROFILER
 
-int64_t kqemu_time;
 int64_t qemu_time;
-int64_t kqemu_exec_count;
 int64_t dev_time;
-int64_t kqemu_ret_int_count;
-int64_t kqemu_ret_excp_count;
-int64_t kqemu_ret_intr_count;
-
 static void do_info_profile(void)
 {
     int64_t total;
+    char buf[MAX_BUF];
+    CPUState *env = mon_get_cpu();
+
     total = qemu_time;
     if (total == 0)
         total = 1;
@@ -1272,24 +1269,12 @@ static void do_info_profile(void)
                 dev_time, dev_time / (double)ticks_per_sec);
     term_printf("qemu time   %" PRId64 " (%0.3f)\n",
                 qemu_time, qemu_time / (double)ticks_per_sec);
-    term_printf("kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%" PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%" PRId64 "\n",
-                kqemu_time, kqemu_time / (double)ticks_per_sec,
-                kqemu_time / (double)total * 100.0,
-                kqemu_exec_count,
-                kqemu_ret_int_count,
-                kqemu_ret_excp_count,
-                kqemu_ret_intr_count);
+    if (accel_profile(env, buf))
+        term_printf(buf);
     qemu_time = 0;
-    kqemu_time = 0;
-    kqemu_exec_count = 0;
     dev_time = 0;
-    kqemu_ret_int_count = 0;
-    kqemu_ret_excp_count = 0;
-    kqemu_ret_intr_count = 0;
-#ifdef USE_KQEMU
-    kqemu_record_dump();
-#endif
 }
+
 #else
 static void do_info_profile(void)
 {
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 12/32] move kqemu externs to kqemu.h
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (12 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 11/32] separate accelerator part of info profiler Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 13/32] move disabling code to kqemu.c instead of vl.c Glauber Costa
                   ` (19 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

move extern definitions to from cpu-all.h to kqemu.h.
Just a step to increase kqemu's degree of separation.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 cpu-all.h |    5 -----
 kqemu.h   |    6 ++++++
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/cpu-all.h b/cpu-all.h
index cdd79bc..0150827 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -1077,14 +1077,9 @@ static inline int64_t profile_getclock(void)
     return cpu_get_real_ticks();
 }
 
-extern int64_t kqemu_time, kqemu_time_start;
 extern int64_t qemu_time, qemu_time_start;
 extern int64_t tlb_flush_time;
-extern int64_t kqemu_exec_count;
 extern int64_t dev_time;
-extern int64_t kqemu_ret_int_count;
-extern int64_t kqemu_ret_excp_count;
-extern int64_t kqemu_ret_intr_count;
 #endif
 
 #endif /* CPU_ALL_H */
diff --git a/kqemu.h b/kqemu.h
index ed25c75..1c7e024 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -32,6 +32,12 @@
 
 #define KQEMU_VERSION 0x010400
 
+extern int64_t kqemu_time, kqemu_time_start;
+extern int64_t kqemu_exec_count;
+extern int64_t kqemu_ret_int_count;
+extern int64_t kqemu_ret_excp_count;
+extern int64_t kqemu_ret_intr_count;
+
 struct kqemu_segment_cache {
     uint16_t selector;
     uint16_t padding1;
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 13/32] move disabling code to kqemu.c instead of vl.c
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (13 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 12/32] move kqemu externs to kqemu.h Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 14/32] set_notdirty goes through accel wrapper Glauber Costa
                   ` (18 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

kqemu is not smp. So instead of testing in vl.c, do the test in kqemu.c,
and just refuse to start if smp_cpus > 1.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c |    2 +-
 vl.c    |    4 ----
 2 files changed, 1 insertions(+), 5 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 0a1d63b..7f24cfc 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -166,7 +166,7 @@ int kqemu_start(void)
     DWORD temp;
 #endif
 
-    if (!kqemu_allowed)
+    if (!kqemu_allowed || cpus > 1)
         return -1;
 
 #ifdef _WIN32
diff --git a/vl.c b/vl.c
index adf5b25..f7bbfbb 100644
--- a/vl.c
+++ b/vl.c
@@ -9469,10 +9469,6 @@ int main(int argc, char **argv)
         exit(1);
     }
 
-#ifdef USE_KQEMU
-    if (smp_cpus > 1)
-        kqemu_allowed = 0;
-#endif
     linux_boot = (kernel_filename != NULL);
     net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF;
 
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 14/32] set_notdirty goes through accel wrapper
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (14 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 13/32] move disabling code to kqemu.c instead of vl.c Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 15/32] wrap modify_page through accel calls Glauber Costa
                   ` (17 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: set_notdirty
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c    |    1 +
 accel.h    |    6 ++++++
 exec-all.h |    1 -
 exec.c     |   18 +++++++-----------
 kqemu.c    |    3 ++-
 5 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/accel.c b/accel.c
index 40dfac6..58ac053 100644
--- a/accel.c
+++ b/accel.c
@@ -23,5 +23,6 @@ QEMUAccel noaccel = {
     .flush_page = accel_nop,
     .info = noaccel_info,
     .profile = accel_nop,
+    .set_notdirty = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index bb56526..76e1f3b 100644
--- a/accel.h
+++ b/accel.h
@@ -10,6 +10,7 @@ typedef struct QEMUAccel {
     void (*flush_page)(CPUState *env, target_ulong addr);
     int (*info)(CPUState *env, char *buf);
     int (*profile)(CPUState *env, char *buf);
+    void (*set_notdirty)(ram_addr_t addr);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -49,4 +50,9 @@ static inline int accel_profile(CPUState *env, char *buf)
 {
    return current_accel->profile(env, buf);
 }
+
+static inline void accel_set_notdirty(target_ulong addr)
+{
+    current_accel->set_notdirty(addr);
+}
 #endif
diff --git a/exec-all.h b/exec-all.h
index 2098fe8..cb2e7c6 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -366,7 +366,6 @@ static inline int can_do_io(CPUState *env)
 #define MSR_QPI_COMMBASE 0xfabe0010
 
 int kqemu_cpu_exec(CPUState *env);
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr);
 void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
                         ram_addr_t phys_offset);
diff --git a/exec.c b/exec.c
index 4f7aa67..fa62167 100644
--- a/exec.c
+++ b/exec.c
@@ -1774,18 +1774,14 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
     if (length == 0)
         return;
     len = length >> TARGET_PAGE_BITS;
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env->kqemu_enabled) {
-        ram_addr_t addr;
-        addr = start;
-        for(i = 0; i < len; i++) {
-            kqemu_set_notdirty(env, addr);
-            addr += TARGET_PAGE_SIZE;
-        }
+
+    ram_addr_t addr;
+    addr = start;
+    for(i = 0; i < len; i++) {
+        accel_set_notdirty(addr);
+        addr += TARGET_PAGE_SIZE;
     }
-#endif
+
     mask = ~dirty_flags;
     p = phys_ram_dirty + (start >> TARGET_PAGE_BITS);
     for(i = 0; i < len; i++)
diff --git a/kqemu.c b/kqemu.c
index 7f24cfc..98ec1a0 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -275,7 +275,7 @@ static void kqemu_flush(CPUState *env, int global)
     nb_pages_to_flush = KQEMU_FLUSH_ALL;
 }
 
-void kqemu_set_notdirty(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_set_notdirty(ram_addr_t ram_addr)
 {
 #ifdef DEBUG
     if (loglevel & CPU_LOG_INT) {
@@ -1113,6 +1113,7 @@ QEMUAccel kqemu_accel = {
     .flush_page = kqemu_flush_page,
     .info = kqemu_info,
     .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 15/32] wrap modify_page through accel calls
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (15 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 14/32] set_notdirty goes through accel wrapper Glauber Costa
@ 2008-10-23 14:18 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 16/32] remove kqemu reference from hw/pc.c Glauber Costa
                   ` (16 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:18 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Yet another accel field: modify_page
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c    |    1 +
 accel.h    |    7 +++++++
 exec-all.h |    1 -
 exec.c     |   27 ++++++++++++---------------
 kqemu.c    |    5 ++++-
 5 files changed, 24 insertions(+), 17 deletions(-)

diff --git a/accel.c b/accel.c
index 58ac053..d615912 100644
--- a/accel.c
+++ b/accel.c
@@ -24,5 +24,6 @@ QEMUAccel noaccel = {
     .info = noaccel_info,
     .profile = accel_nop,
     .set_notdirty = accel_nop,
+    .modify_page = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index 76e1f3b..e232f87 100644
--- a/accel.h
+++ b/accel.h
@@ -11,6 +11,7 @@ typedef struct QEMUAccel {
     int (*info)(CPUState *env, char *buf);
     int (*profile)(CPUState *env, char *buf);
     void (*set_notdirty)(ram_addr_t addr);
+    void (*modify_page)(ram_addr_t addr, int dirty_flags);
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -55,4 +56,10 @@ static inline void accel_set_notdirty(target_ulong addr)
 {
     current_accel->set_notdirty(addr);
 }
+
+static inline void accel_modify_page(target_ulong addr, int dirty_flags)
+{
+    current_accel->modify_page(addr, dirty_flags);
+}
+
 #endif
diff --git a/exec-all.h b/exec-all.h
index cb2e7c6..6c62f06 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -366,7 +366,6 @@ static inline int can_do_io(CPUState *env)
 #define MSR_QPI_COMMBASE 0xfabe0010
 
 int kqemu_cpu_exec(CPUState *env);
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr);
 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
                         ram_addr_t phys_offset);
 void kqemu_record_dump(void);
diff --git a/exec.c b/exec.c
index fa62167..089a91e 100644
--- a/exec.c
+++ b/exec.c
@@ -2378,12 +2378,11 @@ static void notdirty_mem_writeb(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stb_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2403,12 +2402,11 @@ static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stw_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
@@ -2428,12 +2426,11 @@ static void notdirty_mem_writel(void *opaque, target_phys_addr_t ram_addr,
         dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS];
 #endif
     }
+
     stl_p(phys_ram_base + ram_addr, val);
-#ifdef USE_KQEMU
-    if (cpu_single_env->kqemu_enabled &&
-        (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
-        kqemu_modify_page(cpu_single_env, ram_addr);
-#endif
+
+    accel_modify_page(ram_addr, dirty_flags);
+
     dirty_flags |= (0xff & ~CODE_DIRTY_FLAG);
     phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags;
     /* we remove the notdirty callback only if the code has been
diff --git a/kqemu.c b/kqemu.c
index 98ec1a0..5777afd 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -304,7 +304,7 @@ static void kqemu_reset_modified_ram_pages(void)
     nb_modified_ram_pages = 0;
 }
 
-void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
+static void kqemu_modify_page(ram_addr_t ram_addr, int dirty_flags)
 {
     unsigned long page_index;
     int ret;
@@ -312,6 +312,8 @@ void kqemu_modify_page(CPUState *env, ram_addr_t ram_addr)
     DWORD temp;
 #endif
 
+    if ((dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK)
+        return;
     page_index = ram_addr >> TARGET_PAGE_BITS;
     if (!modified_ram_pages_table[page_index]) {
 #if 0
@@ -1114,6 +1116,7 @@ QEMUAccel kqemu_accel = {
     .info = kqemu_info,
     .profile = kqemu_profile,
     .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 16/32] remove kqemu reference from hw/pc.c
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (16 preceding siblings ...)
  2008-10-23 14:18 ` [Qemu-devel] [PATCH 15/32] wrap modify_page through accel calls Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 17/32] build list of available accelerators Glauber Costa
                   ` (15 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Instead, route cpu_get_ticks through accel driver.
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c |    3 +++
 accel.h |   12 ++++++++++++
 hw/pc.c |   13 ++-----------
 kqemu.c |    6 ++++++
 4 files changed, 23 insertions(+), 11 deletions(-)

diff --git a/accel.c b/accel.c
index d615912..08a85c2 100644
--- a/accel.c
+++ b/accel.c
@@ -25,5 +25,8 @@ QEMUAccel noaccel = {
     .profile = accel_nop,
     .set_notdirty = accel_nop,
     .modify_page = accel_nop,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_ticks,
+#endif
 };
 
diff --git a/accel.h b/accel.h
index e232f87..cf0d752 100644
--- a/accel.h
+++ b/accel.h
@@ -12,6 +12,9 @@ typedef struct QEMUAccel {
     int (*profile)(CPUState *env, char *buf);
     void (*set_notdirty)(ram_addr_t addr);
     void (*modify_page)(ram_addr_t addr, int dirty_flags);
+#ifndef CONFIG_USER_ONLY
+    uint64_t (*get_real_ticks)(void);
+#endif
 } QEMUAccel;
 
 extern QEMUAccel *current_accel;
@@ -62,4 +65,13 @@ static inline void accel_modify_page(target_ulong addr, int dirty_flags)
     current_accel->modify_page(addr, dirty_flags);
 }
 
+int64_t cpu_get_ticks(void);
+
+#ifndef CONFIG_USER_ONLY
+static inline uint64_t accel_get_real_ticks(void)
+{
+   return current_accel->get_real_ticks();
+}
+#endif
+
 #endif
diff --git a/hw/pc.c b/hw/pc.c
index 34683e7..2f56c1f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -33,6 +33,7 @@
 #include "boards.h"
 #include "console.h"
 #include "fw_cfg.h"
+#include "accel.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -75,17 +76,7 @@ static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
 /* TSC handling */
 uint64_t cpu_get_tsc(CPUX86State *env)
 {
-    /* Note: when using kqemu, it is more logical to return the host TSC
-       because kqemu does not trap the RDTSC instruction for
-       performance reasons */
-#ifdef USE_KQEMU
-    if (env->kqemu_enabled) {
-        return cpu_get_real_ticks();
-    } else
-#endif
-    {
-        return cpu_get_ticks();
-    }
+    return accel_get_real_ticks();
 }
 
 /* SMM support */
diff --git a/kqemu.c b/kqemu.c
index 5777afd..6bce892 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1117,6 +1117,12 @@ QEMUAccel kqemu_accel = {
     .profile = kqemu_profile,
     .set_notdirty = kqemu_set_notdirty,
     .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    /* Note: when using kqemu, it is more logical to return the host TSC
+       because kqemu does not trap the RDTSC instruction for
+       performance reasons */
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 17/32] build list of available accelerators
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (17 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 16/32] remove kqemu reference from hw/pc.c Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 13:45   ` [Qemu-devel] " Avi Kivity
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 18/32] provide --accel option Glauber Costa
                   ` (14 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

instead of hardcoding kqemu_start() in exec.c, which would require
such a hack for all available accelerators, semantics of register_qemu_accel()
is changed a little bit. It only builds a list of available accelerators.
The last one registered is the first tried.

This is a temporary solution, since we don't control exactly the order in which
things are loaded by the constructor attributes. The final goal is to have command
line switches and priority lists to determine that.

"info accelerator" is changed to accomodate it. It now prints a list of available
accelerators, and only if one of them is active, a detailed description of it is printed.

Signed-off-by: Glauber Costa <glommer@redhat.com>
Signed-off-by: Jes Sorensen <jes@sgi.com>
---
 accel.c   |    3 ++
 accel.h   |   63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 exec.c    |    3 --
 kqemu.c   |    5 ++-
 monitor.c |   12 +++++++++-
 vl.c      |    7 ++++++
 6 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/accel.c b/accel.c
index 08a85c2..74f7c89 100644
--- a/accel.c
+++ b/accel.c
@@ -2,6 +2,7 @@
 #include "accel.h"
 
 QEMUAccel *current_accel;
+QEMUCont *head = NULL;
 
 int _accel_nop(void)
 {
@@ -17,8 +18,10 @@ int noaccel_info(CPUState *env, char *buf)
 
 /* Accelerator wrapper for the no-accel (raw qemu) case */
 QEMUAccel noaccel = {
+    .name = "none",
     .cpu_interrupt = accel_nop,
     .init_env = accel_nop,
+    .start = accel_nop,
     .flush_cache = accel_nop,
     .flush_page = accel_nop,
     .info = noaccel_info,
diff --git a/accel.h b/accel.h
index cf0d752..3e49a93 100644
--- a/accel.h
+++ b/accel.h
@@ -4,8 +4,10 @@
 #define MAX_INFO_BUF 1024
 
 typedef struct QEMUAccel {
+    char *name;
     void (*cpu_interrupt)(CPUState *env);
     void (*init_env)(CPUState *env);
+    int (*start)(int cpus);
     void (*flush_cache)(CPUState *env, int global);
     void (*flush_page)(CPUState *env, target_ulong addr);
     int (*info)(CPUState *env, char *buf);
@@ -17,12 +19,51 @@ typedef struct QEMUAccel {
 #endif
 } QEMUAccel;
 
+typedef struct QEMUCont {
+    QEMUAccel *acc;
+    int active;
+    struct QEMUCont *next;
+} QEMUCont;
+
 extern QEMUAccel *current_accel;
 extern QEMUAccel noaccel;
+#ifdef USE_KQEMU
+extern QEMUAccel kqemu_accel;
+#endif
 
-static inline void register_qemu_accel(QEMUAccel *accel)
+extern QEMUCont *head;
+void *qemu_mallocz(size_t size);
+
+static inline int register_qemu_accel(QEMUAccel *accel)
 {
-    current_accel = accel;
+    QEMUCont *new, *tmp, *last = NULL;
+
+    for (tmp = head, last; tmp; tmp = tmp->next) {
+        /* we disallow registering the same accelerator twice */
+        if (tmp->acc ==  accel)
+            return -1;
+
+        if (!tmp->next)
+            last = tmp;
+    }
+
+    new = qemu_mallocz(sizeof(*head));
+
+    new->acc = accel;
+    new->active = 0;
+    new->next = NULL;
+
+    if (!head)
+        head = new;
+    else
+        last->next = new;
+
+    return 0;
+}
+
+static inline QEMUCont *get_accel_head(void)
+{
+    return head;
 }
 
 static inline void accel_cpu_interrupt(CPUState *env)
@@ -30,6 +71,24 @@ static inline void accel_cpu_interrupt(CPUState *env)
     current_accel->cpu_interrupt(env);
 }
 
+static inline int accel_start(int cpus)
+{
+    int status = -1;
+    /* The top accelerator in the list gets tried first, but if it fails,
+     * keep trying until one of them succeeds or we exhaust the list */
+    QEMUCont *tmp = head;
+    while (tmp) {
+        if (tmp->acc && tmp->acc->start && (!(tmp->acc->start(cpus))) ) {
+            tmp->active = 1;
+            current_accel = tmp->acc;
+            status = 0;
+            break;
+        }
+        tmp = tmp->next;
+    }
+    return status;
+}
+
 static inline void accel_init_env(CPUState *env)
 {
     current_accel->init_env(env);
diff --git a/exec.c b/exec.c
index 089a91e..005785a 100644
--- a/exec.c
+++ b/exec.c
@@ -497,9 +497,6 @@ void cpu_exec_init_all(unsigned long tb_size)
 #if !defined(CONFIG_USER_ONLY)
     io_mem_init();
 #endif
-#ifdef USE_KQEMU
-    kqemu_start();
-#endif
 }
 
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
diff --git a/kqemu.c b/kqemu.c
index 6bce892..68ec917 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -158,7 +158,7 @@ static void kqemu_update_cpuid(CPUState *env)
 
 QEMUAccel kqemu_accel;
 
-int kqemu_start(void)
+static int kqemu_start(int cpus)
 {
     struct kqemu_init kinit;
     int ret, version;
@@ -240,7 +240,6 @@ int kqemu_start(void)
     }
     nb_pages_to_flush = 0;
     nb_ram_pages_to_update = 0;
-    register_qemu_accel(&kqemu_accel);
 
     qpi_init();
     return 0;
@@ -1109,8 +1108,10 @@ static int kqemu_profile(CPUState *env, char *buf)
 }
 
 QEMUAccel kqemu_accel = {
+    .name = "KQEMU",
     .cpu_interrupt = kqemu_cpu_interrupt,
     .init_env = kqemu_init_env,
+    .start = kqemu_start,
     .flush_cache = kqemu_flush,
     .flush_page = kqemu_flush_page,
     .info = kqemu_info,
diff --git a/monitor.c b/monitor.c
index 42a1b02..fe915d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1234,6 +1234,15 @@ static void mem_info(void)
 }
 #endif
 
+static int do_accel_do_list(void)
+{
+    QEMUCont *tmp;
+    for (tmp= get_accel_head(); tmp != NULL; tmp = tmp->next)
+    {
+        term_printf("%c %s\n", tmp->active ? '*' : ' ', tmp->acc->name);
+    }
+}
+
 static void do_info_accelerator(void)
 {
     char buf[MAX_INFO_BUF];
@@ -1246,10 +1255,9 @@ static void do_info_accelerator(void)
         return;
     }
 
+    do_accel_do_list();
     if (accel_info(env, buf))
         term_printf(buf);
-    else
-        term_printf("No accelerator present\n");
 }
 
 #ifdef CONFIG_PROFILER
diff --git a/vl.c b/vl.c
index f7bbfbb..c584ea3 100644
--- a/vl.c
+++ b/vl.c
@@ -140,6 +140,7 @@
 #include "disas.h"
 
 #include "exec-all.h"
+#include "accel.h"
 
 #define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
 #define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown"
@@ -8815,6 +8816,7 @@ int main(int argc, char **argv)
     }
 #endif
 
+    register_qemu_accel(&kqemu_accel);
     register_qemu_accel(&noaccel);
 
     register_machines();
@@ -9589,6 +9591,11 @@ int main(int argc, char **argv)
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
 
+    if (accel_start(smp_cpus)) {
+	    fprintf(stderr, "qemu: error, no suitable accelerator found\n");
+	    exit(1);
+    }
+
     bdrv_init();
 
     /* we always create the cdrom drive, even if no disk is there */
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 18/32] provide --accel option
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (18 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 17/32] build list of available accelerators Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 19/32] add hook to cpu_register_physical_memory Glauber Costa
                   ` (13 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

The --accel option will provide us the ability of defining which
accelerator to pick at run time. It has the advantage of not using
the not-well-accepted constructor directives, and also, of stabilishing
a way to define priorities among accelerators.

The ones registered first, are tried first.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 vl.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/vl.c b/vl.c
index c584ea3..964205d 100644
--- a/vl.c
+++ b/vl.c
@@ -255,6 +255,13 @@ static QEMUTimer *icount_vm_timer;
 
 uint8_t qemu_uuid[16];
 
+QEMUAccel *available_accels[] = {
+/* list of available accelerators */
+#ifdef USE_KQEMU
+    &kqemu_accel,
+#endif
+};
+
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
 /***********************************************************/
@@ -8355,6 +8362,7 @@ enum {
     QEMU_OPTION_no_quit,
     QEMU_OPTION_pidfile,
     QEMU_OPTION_no_kqemu,
+    QEMU_OPTION_accel,
     QEMU_OPTION_kernel_kqemu,
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
@@ -8442,6 +8450,7 @@ static const QEMUOption qemu_options[] = {
     { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
     { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
 #endif
+    { "accel", HAS_ARG, QEMU_OPTION_accel},
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
 #endif
@@ -8816,9 +8825,6 @@ int main(int argc, char **argv)
     }
 #endif
 
-    register_qemu_accel(&kqemu_accel);
-    register_qemu_accel(&noaccel);
-
     register_machines();
     machine = first_machine;
     cpu_model = NULL;
@@ -9267,6 +9273,15 @@ int main(int argc, char **argv)
                 kqemu_allowed = 2;
                 break;
 #endif
+            case QEMU_OPTION_accel:
+                {
+                    int i;
+                    for (i = 0; i < ARRAY_SIZE(available_accels); i++) {
+                        if (!strcasecmp(optarg, available_accels[i]->name))
+                            register_qemu_accel(available_accels[i]);
+                    }
+                }
+                break;
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
                 break;
@@ -9408,6 +9423,9 @@ int main(int argc, char **argv)
         exit(1);
     }
 
+    /* Basic handler for the noaccel case */
+    register_qemu_accel(&noaccel);
+
     if (nographic) {
        if (serial_device_index == 0)
            serial_devices[0] = "stdio";
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 19/32] add hook to cpu_register_physical_memory
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (19 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 18/32] provide --accel option Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
                   ` (12 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

kqemu has a hook in it, so add an accel wrapper.
However, we still provide a double underlined version
which does not call the wrapper. That's basically because kqemu
call cpu_register_physical_memory itself during its initialization.

Signed-off-by: Glauber Costa <gcosta@redhat.com>
---
 accel.c   |    1 +
 accel.h   |    9 +++++++++
 cpu-all.h |    4 ++++
 exec.c    |   32 +++++++++++++++++++-------------
 kqemu.c   |    3 ++-
 5 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/accel.c b/accel.c
index 74f7c89..bf1194d 100644
--- a/accel.c
+++ b/accel.c
@@ -31,5 +31,6 @@ QEMUAccel noaccel = {
 #ifndef CONFIG_USER_ONLY
     .get_real_ticks = cpu_get_ticks,
 #endif
+    .register_physical_memory = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index 3e49a93..dbb6372 100644
--- a/accel.h
+++ b/accel.h
@@ -17,6 +17,9 @@ typedef struct QEMUAccel {
 #ifndef CONFIG_USER_ONLY
     uint64_t (*get_real_ticks)(void);
 #endif
+    void (*register_physical_memory)(uint64_t start_addr,
+                                     ram_addr_t size, ram_addr_t phys_offset);
+
 } QEMUAccel;
 
 typedef struct QEMUCont {
@@ -133,4 +136,10 @@ static inline uint64_t accel_get_real_ticks(void)
 }
 #endif
 
+static inline void accel_register_phys_mem(uint64_t start_addr,
+                                           ram_addr_t size,
+                                           ram_addr_t phys_offset)
+{
+    current_accel->register_physical_memory(start_addr, size, phys_offset);
+}
 #endif
diff --git a/cpu-all.h b/cpu-all.h
index 0150827..edefb45 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -863,6 +863,10 @@ extern ram_addr_t ram_size;
 typedef void CPUWriteMemoryFunc(void *opaque, target_phys_addr_t addr, uint32_t value);
 typedef uint32_t CPUReadMemoryFunc(void *opaque, target_phys_addr_t addr);
 
+/* this is a private version, meant for internal use of accelerators */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset);
 void cpu_register_physical_memory(target_phys_addr_t start_addr,
                                   ram_addr_t size,
                                   ram_addr_t phys_offset);
diff --git a/exec.c b/exec.c
index 005785a..80b8a78 100644
--- a/exec.c
+++ b/exec.c
@@ -2183,12 +2183,13 @@ static void *subpage_init (target_phys_addr_t base, ram_addr_t *phys,
         }                                                               \
     } while (0)
 
-/* register physical memory. 'size' must be a multiple of the target
-   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
-   io memory page */
-void cpu_register_physical_memory(target_phys_addr_t start_addr,
-                                  ram_addr_t size,
-                                  ram_addr_t phys_offset)
+/* Use this version of cpu registering physical memory in accel-specific code. It exists
+ * to avoid chicken and egg problems with code that might need to register memory in qemu,
+ * but not with the underlying accelerator
+ */
+void __cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                    ram_addr_t size,
+                                    ram_addr_t phys_offset)
 {
     target_phys_addr_t addr, end_addr;
     PhysPageDesc *p;
@@ -2196,13 +2197,6 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     ram_addr_t orig_size = size;
     void *subpage;
 
-#ifdef USE_KQEMU
-    /* XXX: should not depend on cpu context */
-    env = first_cpu;
-    if (env && env->kqemu_enabled) {
-        kqemu_set_phys_mem(start_addr, size, phys_offset);
-    }
-#endif
     size = (size + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK;
     end_addr = start_addr + (target_phys_addr_t)size;
     for(addr = start_addr; addr != end_addr; addr += TARGET_PAGE_SIZE) {
@@ -2260,6 +2254,18 @@ void cpu_register_physical_memory(target_phys_addr_t start_addr,
     }
 }
 
+/* register physical memory. 'size' must be a multiple of the target
+   page size. If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
+   io memory page */
+void cpu_register_physical_memory(target_phys_addr_t start_addr,
+                                  ram_addr_t size,
+                                  ram_addr_t phys_offset)
+{
+    accel_register_phys_mem(start_addr, size, phys_offset);
+
+    __cpu_register_physical_memory(start_addr, size, phys_offset);
+}
+
 /* XXX: temporary until new memory mapping API */
 ram_addr_t cpu_get_physical_page_desc(target_phys_addr_t addr)
 {
diff --git a/kqemu.c b/kqemu.c
index 68ec917..f4d905a 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1048,7 +1048,7 @@ static void qpi_init(void)
     qpi_io_memory = cpu_register_io_memory(0, 
                                            qpi_mem_read, 
                                            qpi_mem_write, NULL);
-    cpu_register_physical_memory(kqemu_comm_base & ~0xfff, 
+    __cpu_register_physical_memory(kqemu_comm_base & ~0xfff,
                                  0x1000, qpi_io_memory);
 }
 
@@ -1124,6 +1124,7 @@ QEMUAccel kqemu_accel = {
        performance reasons */
     .get_real_ticks = cpu_get_real_ticks,
 #endif
+    .register_physical_memory = kqemu_set_phys_mem,
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 20/32] accel_trace_io
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (20 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 19/32] add hook to cpu_register_physical_memory Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:20   ` [Qemu-devel] " Anthony Liguori
  2008-10-25 11:10   ` [Qemu-devel] " andrzej zaborowski
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 21/32] get_env accel wrapper Glauber Costa
                   ` (11 subsequent siblings)
  33 siblings, 2 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

kqemu keeps trace of the last io done. Do it through
an accel_wrapper.

Signed-off-by: Glauber Costa <gcosta@redhat.com>
---
 accel.c            |    2 ++
 accel.h            |   13 ++++++++++++-
 cpu-exec.c         |    9 ++-------
 kqemu.c            |   18 ++++++++++++++++++
 softmmu_template.h |   10 ++++------
 vl.c               |   30 ++++++------------------------
 6 files changed, 44 insertions(+), 38 deletions(-)

diff --git a/accel.c b/accel.c
index bf1194d..0890039 100644
--- a/accel.c
+++ b/accel.c
@@ -32,5 +32,7 @@ QEMUAccel noaccel = {
     .get_real_ticks = cpu_get_ticks,
 #endif
     .register_physical_memory = accel_nop,
+    .trace_io = accel_nop,
+    .break_loop = accel_nop,
 };
 
diff --git a/accel.h b/accel.h
index dbb6372..b37175b 100644
--- a/accel.h
+++ b/accel.h
@@ -19,7 +19,8 @@ typedef struct QEMUAccel {
 #endif
     void (*register_physical_memory)(uint64_t start_addr,
                                      ram_addr_t size, ram_addr_t phys_offset);
-
+    void (*trace_io)(CPUState *env);
+    int (*break_loop)(CPUState *env);
 } QEMUAccel;
 
 typedef struct QEMUCont {
@@ -142,4 +143,14 @@ static inline void accel_register_phys_mem(uint64_t start_addr,
 {
     current_accel->register_physical_memory(start_addr, size, phys_offset);
 }
+
+static inline void accel_trace_io(CPUState *env)
+{
+    current_accel->trace_io(env);
+}
+
+static inline int accel_break_loop(CPUState *env)
+{
+    return current_accel->break_loop(env);
+}
 #endif
diff --git a/cpu-exec.c b/cpu-exec.c
index 88b7d6f..18908d5 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -36,6 +36,7 @@
 #include <signal.h>
 #include <sys/ucontext.h>
 #endif
+#include "accel.h"
 
 #if defined(__sparc__) && !defined(HOST_SOLARIS)
 // Work around ugly bugs in glibc that mangle global register contents
@@ -646,13 +647,7 @@ int cpu_exec(CPUState *env1)
                 }
                 /* reset soft MMU for next block (it can currently
                    only be set by a memory fault) */
-#if defined(USE_KQEMU)
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
-                if (kqemu_is_ok(env) &&
-                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
-                    cpu_loop_exit();
-                }
-#endif
+                accel_break_loop(env);
             } /* for(;;) */
         } else {
             env_to_regs();
diff --git a/kqemu.c b/kqemu.c
index f4d905a..d38d0e3 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1107,6 +1107,22 @@ static int kqemu_profile(CPUState *env, char *buf)
     return len;
 }
 
+static void kqemu_trace_io(CPUState *env)
+{
+    if (env)
+        env->last_io_time = cpu_get_time_fast();
+}
+
+static int kqemu_break_loop(CPUState *env)
+{
+#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
+    if (kqemu_is_ok(env) &&
+        (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
+        return 1;
+    }
+    return 0;
+}
+
 QEMUAccel kqemu_accel = {
     .name = "KQEMU",
     .cpu_interrupt = kqemu_cpu_interrupt,
@@ -1125,6 +1141,8 @@ QEMUAccel kqemu_accel = {
     .get_real_ticks = cpu_get_real_ticks,
 #endif
     .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
 };
 
 #endif
diff --git a/softmmu_template.h b/softmmu_template.h
index 98dd378..4945352 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -47,6 +47,8 @@
 #define ADDR_READ addr_read
 #endif
 
+#include "accel.h"
+
 static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
                                                         int mmu_idx,
                                                         void *retaddr);
@@ -75,9 +77,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
     res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return res;
 }
 
@@ -220,9 +220,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
     io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
 #endif
 #endif /* SHIFT > 2 */
-#ifdef USE_KQEMU
-    env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
diff --git a/vl.c b/vl.c
index 964205d..e64becb 100644
--- a/vl.c
+++ b/vl.c
@@ -420,10 +420,7 @@ void cpu_outb(CPUState *env, int addr, int val)
         fprintf(logfile, "outb: %04x %02x\n", addr, val);
 #endif
     ioport_write(0, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outw(CPUState *env, int addr, int val)
@@ -433,10 +430,7 @@ void cpu_outw(CPUState *env, int addr, int val)
         fprintf(logfile, "outw: %04x %04x\n", addr, val);
 #endif
     ioport_write(1, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 void cpu_outl(CPUState *env, int addr, int val)
@@ -446,10 +440,7 @@ void cpu_outl(CPUState *env, int addr, int val)
         fprintf(logfile, "outl: %04x %08x\n", addr, val);
 #endif
     ioport_write(2, addr, val);
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
 }
 
 int cpu_inb(CPUState *env, int addr)
@@ -460,10 +451,7 @@ int cpu_inb(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inb : %04x %02x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -475,10 +463,7 @@ int cpu_inw(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inw : %04x %04x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
@@ -490,10 +475,7 @@ int cpu_inl(CPUState *env, int addr)
     if (loglevel & CPU_LOG_IOPORT)
         fprintf(logfile, "inl : %04x %08x\n", addr, val);
 #endif
-#ifdef USE_KQEMU
-    if (env)
-        env->last_io_time = cpu_get_time_fast();
-#endif
+    accel_trace_io(env);
     return val;
 }
 
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 21/32] get_env accel wrapper
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (21 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 13:36   ` [Qemu-devel] " Avi Kivity
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 22/32] add next_cpu_index Glauber Costa
                   ` (10 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

Allow the current accelerator to provide it's own, customized
address of the CPUState structure used for the env variable.

Signed-off-by: Glauber Costa <gcosta@redhat.com>
---
 accel.c              |    6 ++++++
 accel.h              |    8 ++++++++
 kqemu.c              |   12 ++++++++++--
 kqemu.h              |   10 ++++++++++
 target-i386/cpu.h    |    1 -
 target-i386/helper.c |    2 +-
 6 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/accel.c b/accel.c
index 0890039..28dd2ee 100644
--- a/accel.c
+++ b/accel.c
@@ -14,6 +14,11 @@ int noaccel_info(CPUState *env, char *buf)
     return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
 }
 
+CPUState *noaccel_get_env(void)
+{
+    return qemu_mallocz(sizeof(CPUState));
+}
+
 #define accel_nop ((void *)_accel_nop)
 
 /* Accelerator wrapper for the no-accel (raw qemu) case */
@@ -21,6 +26,7 @@ QEMUAccel noaccel = {
     .name = "none",
     .cpu_interrupt = accel_nop,
     .init_env = accel_nop,
+    .get_env = noaccel_get_env,
     .start = accel_nop,
     .flush_cache = accel_nop,
     .flush_page = accel_nop,
diff --git a/accel.h b/accel.h
index b37175b..0c5ff33 100644
--- a/accel.h
+++ b/accel.h
@@ -6,6 +6,7 @@
 typedef struct QEMUAccel {
     char *name;
     void (*cpu_interrupt)(CPUState *env);
+    CPUState *(*get_env)(void);
     void (*init_env)(CPUState *env);
     int (*start)(int cpus);
     void (*flush_cache)(CPUState *env, int global);
@@ -33,10 +34,12 @@ extern QEMUAccel *current_accel;
 extern QEMUAccel noaccel;
 #ifdef USE_KQEMU
 extern QEMUAccel kqemu_accel;
+extern QEMUAccel kqemu_kernel_accel;
 #endif
 
 extern QEMUCont *head;
 void *qemu_mallocz(size_t size);
+extern CPUState *noaccel_get_env(void);
 
 static inline int register_qemu_accel(QEMUAccel *accel)
 {
@@ -93,6 +96,11 @@ static inline int accel_start(int cpus)
     return status;
 }
 
+static inline CPUState *accel_get_env(void)
+{
+    return current_accel->get_env();
+}
+
 static inline void accel_init_env(CPUState *env)
 {
     current_accel->init_env(env);
diff --git a/kqemu.c b/kqemu.c
index d38d0e3..5ca0f76 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1110,23 +1110,31 @@ static int kqemu_profile(CPUState *env, char *buf)
 static void kqemu_trace_io(CPUState *env)
 {
     if (env)
-        env->last_io_time = cpu_get_time_fast();
+        kqemu_cpu_field(env,last_io_time) = cpu_get_time_fast();
 }
 
 static int kqemu_break_loop(CPUState *env)
 {
 #define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
     if (kqemu_is_ok(env) &&
-        (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
+        (cpu_get_time_fast() - kqemu_cpu_field(env,last_io_time)) >= MIN_CYCLE_BEFORE_SWITCH) {
         return 1;
     }
     return 0;
 }
 
+static CPUState *kqemu_get_env(void)
+{
+    KQEMUCPUState *kenv;
+    kenv = qemu_mallocz(sizeof(KQEMUCPUState));
+    return &kenv->env;
+}
+
 QEMUAccel kqemu_accel = {
     .name = "KQEMU",
     .cpu_interrupt = kqemu_cpu_interrupt,
     .init_env = kqemu_init_env,
+    .get_env = kqemu_get_env,
     .start = kqemu_start,
     .flush_cache = kqemu_flush,
     .flush_page = kqemu_flush_page,
diff --git a/kqemu.h b/kqemu.h
index 1c7e024..cf14179 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -157,4 +157,14 @@ struct kqemu_phys_mem {
 #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
 #endif
 
+typedef struct KQEMUCPUstate {
+    int kqemu_enabled;
+    int last_io_time;
+    CPUState env;
+} KQEMUCPUState;
+
+#define kqemu_cpu_field(env, field) (*({ \
+    KQEMUCPUState *__c = container_of(env, KQEMUCPUState, env); \
+    &__c->field; }))
+
 #endif /* KQEMU_H */
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3c11e0f..8a2d797 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -608,7 +608,6 @@ typedef struct CPUX86State {
 
 #ifdef USE_KQEMU
     int kqemu_enabled;
-    int last_io_time;
 #endif
     /* in order to simplify APIC support, we leave this pointer to the
        user */
diff --git a/target-i386/helper.c b/target-i386/helper.c
index b981b92..5ff051f 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -98,7 +98,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
     CPUX86State *env;
     static int inited;
 
-    env = qemu_mallocz(sizeof(CPUX86State));
+    env = accel_get_env();
     if (!env)
         return NULL;
     cpu_exec_init(env);
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 22/32] add next_cpu_index
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (22 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 21/32] get_env accel wrapper Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:21   ` [Qemu-devel] " Anthony Liguori
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 23/32] move cpu_get_time_fast to kqemu.c Glauber Costa
                   ` (9 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

From: Glauber Costa <gcosta@redhat.com>

separate the logic for calculating the next cpu index
from cpu creation. It will allow others to query what's
the next cpu index to be created before cpu creation.

Signed-off-by: Glauber Costa <gcosta@redhat.com>
---
 exec.c |   22 ++++++++++++++--------
 1 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/exec.c b/exec.c
index 80b8a78..7fe7eeb 100644
--- a/exec.c
+++ b/exec.c
@@ -526,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
 }
 #endif
 
-void cpu_exec_init(CPUState *env)
+int next_cpu_index(void)
 {
     CPUState **penv;
-    int cpu_index;
+    int cpu_index = 0;
 
-    env->next_cpu = NULL;
     penv = &first_cpu;
-    cpu_index = 0;
+
     while (*penv != NULL) {
         penv = (CPUState **)&(*penv)->next_cpu;
         cpu_index++;
     }
-    env->cpu_index = cpu_index;
+    return cpu_index;
+}
+
+void cpu_exec_init(CPUState *env)
+{
+    env->next_cpu = NULL;
+    env->cpu_index = next_cpu_index();
     env->nb_watchpoints = 0;
-    *penv = env;
+    if (env->cpu_index == 0)
+        first_cpu = env;
 #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
-    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
+    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
                     cpu_common_save, cpu_common_load, env);
-    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
+    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
                     cpu_save, cpu_load, env);
 #endif
 }
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 23/32] move cpu_get_time_fast to kqemu.c
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (23 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 22/32] add next_cpu_index Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
                   ` (8 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

remove it from generic code
Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c           |    7 +++++++
 target-i386/cpu.h |    9 ---------
 2 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 5ca0f76..16ebe7d 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -90,6 +90,13 @@ uint8_t *modified_ram_pages_table;
 int qpi_io_memory;
 uint32_t kqemu_comm_base; /* physical address of the QPI communication page */
 
+static inline int cpu_get_time_fast(void)
+{
+    int low, high;
+    asm volatile("rdtsc" : "=a" (low), "=d" (high));
+    return low;
+}
+
 #define cpuid(index, eax, ebx, ecx, edx) \
   asm volatile ("cpuid" \
                 : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) \
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 8a2d797..6310529 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -726,15 +726,6 @@ void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
 #define X86_DUMP_FPU  0x0001 /* dump FPU state too */
 #define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
 
-#ifdef USE_KQEMU
-static inline int cpu_get_time_fast(void)
-{
-    int low, high;
-    asm volatile("rdtsc" : "=a" (low), "=d" (high));
-    return low;
-}
-#endif
-
 #define TARGET_PAGE_BITS 12
 
 #define CPUState CPUX86State
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (24 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 23/32] move cpu_get_time_fast to kqemu.c Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 13:38   ` [Qemu-devel] " Jan Kiszka
  2008-10-23 14:23   ` Anthony Liguori
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 25/32] provide accel hook for cpu_exec Glauber Costa
                   ` (7 subsequent siblings)
  33 siblings, 2 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

kqemu is still too much spread around. The proper fix
usually involves rethinking a bit of kqemu logic so for now,
just check whether or not kqemu is enabled. If the kqemu accelerator
is not present, consider it not. Otherwise, check env field.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 cpu-exec.c |    2 +-
 kqemu.c    |   21 +++++++++++++++++++++
 kqemu.h    |    3 +++
 3 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/cpu-exec.c b/cpu-exec.c
index 18908d5..b47cf43 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
                 {
                     if (next_tb != 0 &&
 #ifdef USE_KQEMU
-                        (env->kqemu_enabled != 2) &&
+                        (!kqemu_kernel_enabled(env)) &&
 #endif
                         tb->page_addr[1] == -1) {
                     tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
diff --git a/kqemu.c b/kqemu.c
index 16ebe7d..f99a4f1 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -126,6 +126,27 @@ static int is_cpuid_supported(void)
 }
 #endif
 
+/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
+ * altogether
+ */
+int kqemu_is_enabled(CPUState *env)
+{
+    if (strcasecmp(current_accel->name, "kqemu")) {
+        return 0;
+    }
+
+    return env->kqemu_enabled;
+
+}
+
+int kqemu_kernel_enabled(CPUState *env)
+{
+    if (strcasecmp(current_accel->name, "kqemu")) {
+        return 0;
+    }
+    return env->kqemu_enabled == 2;
+}
+
 static void kqemu_update_cpuid(CPUState *env)
 {
     int critical_features_mask, features, ext_features, ext_features_mask;
diff --git a/kqemu.h b/kqemu.h
index cf14179..62ba1d9 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -157,6 +157,9 @@ struct kqemu_phys_mem {
 #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
 #endif
 
+int kqemu_is_enabled(CPUState *env);
+int kqemu_kernel_enabled(CPUState *env);
+
 typedef struct KQEMUCPUstate {
     int kqemu_enabled;
     int last_io_time;
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 25/32] provide accel hook for cpu_exec
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (25 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 26/32] provide two accelerators for kqemu Glauber Costa
                   ` (6 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

let kqemu_cpu_exec be called through an accelerator hook.
Some parts of what was done in cpu_execution cannot go to a
separate functions, because of code generator constraints:
compute_all() is an example, because the function definition
will get no parameters and yet expect env to be at AREG0. This
expects a particular frame that is destroyed by function calls.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.c    |    7 +++++++
 accel.h    |    6 ++++++
 cpu-exec.c |    5 ++---
 exec-all.h |    1 -
 kqemu.c    |    5 +++--
 5 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/accel.c b/accel.c
index 28dd2ee..8d635f0 100644
--- a/accel.c
+++ b/accel.c
@@ -1,4 +1,5 @@
 #include "hw/hw.h"
+#include "exec-all.h"
 #include "accel.h"
 
 QEMUAccel *current_accel;
@@ -19,6 +20,11 @@ CPUState *noaccel_get_env(void)
     return qemu_mallocz(sizeof(CPUState));
 }
 
+int noaccel_cpu_exec(CPUState *env)
+{
+    return EXEC_EXIT_SOFTMMU;
+}
+
 #define accel_nop ((void *)_accel_nop)
 
 /* Accelerator wrapper for the no-accel (raw qemu) case */
@@ -40,5 +46,6 @@ QEMUAccel noaccel = {
     .register_physical_memory = accel_nop,
     .trace_io = accel_nop,
     .break_loop = accel_nop,
+    .cpu_exec = noaccel_cpu_exec,
 };
 
diff --git a/accel.h b/accel.h
index 0c5ff33..1741f06 100644
--- a/accel.h
+++ b/accel.h
@@ -22,6 +22,7 @@ typedef struct QEMUAccel {
                                      ram_addr_t size, ram_addr_t phys_offset);
     void (*trace_io)(CPUState *env);
     int (*break_loop)(CPUState *env);
+    int (*cpu_exec)(CPUState *env);
 } QEMUAccel;
 
 typedef struct QEMUCont {
@@ -161,4 +162,9 @@ static inline int accel_break_loop(CPUState *env)
 {
     return current_accel->break_loop(env);
 }
+
+static inline int accel_cpu_exec(CPUState *env)
+{
+    return current_accel->cpu_exec(env);
+}
 #endif
diff --git a/cpu-exec.c b/cpu-exec.c
index b47cf43..a0b6055 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -336,9 +336,9 @@ int cpu_exec(CPUState *env1)
                 }
                 env->exception_index = -1;
             }
-#ifdef USE_KQEMU
+
             env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
-            ret = kqemu_cpu_exec(env);
+            ret = accel_cpu_exec(env);
             env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
             if (ret == EXEC_EXIT_INTR) {
                 /* exception */
@@ -353,7 +353,6 @@ int cpu_exec(CPUState *env1)
                     longjmp(env->jmp_env, 1);
                 }
             }
-#endif
 
             next_tb = 0; /* force lookup of first TB */
             for(;;) {
diff --git a/exec-all.h b/exec-all.h
index 6c62f06..8228746 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -365,7 +365,6 @@ static inline int can_do_io(CPUState *env)
 
 #define MSR_QPI_COMMBASE 0xfabe0010
 
-int kqemu_cpu_exec(CPUState *env);
 void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
                         ram_addr_t phys_offset);
 void kqemu_record_dump(void);
diff --git a/kqemu.c b/kqemu.c
index f99a4f1..5162d55 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -731,7 +731,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
     sc->base = ksc->base;
 }
 
-int kqemu_do_cpu_exec(CPUState *env)
+static int kqemu_do_cpu_exec(CPUState *env)
 {
     struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
     int ret, cpl, i;
@@ -981,7 +981,7 @@ int kqemu_do_cpu_exec(CPUState *env)
     return EXEC_EXIT_DONE;
 }
 
-int kqemu_cpu_exec(CPUState *env)
+static int kqemu_cpu_exec(CPUState *env)
 {
 
     int ret = EXEC_EXIT_SOFTMMU;
@@ -1179,6 +1179,7 @@ QEMUAccel kqemu_accel = {
     .register_physical_memory = kqemu_set_phys_mem,
     .trace_io = kqemu_trace_io,
     .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
 };
 
 #endif
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 26/32] provide two accelerators for kqemu
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (26 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 25/32] provide accel hook for cpu_exec Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator Glauber Costa
                   ` (5 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

They are mostly equal, just ease the management of accel
selecting options.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c  |  114 +++++++++++++++++++++++++++++++++++++++----------------------
 kqemu.h  |    1 -
 sysemu.h |    5 ---
 vl.c     |   19 +----------
 4 files changed, 74 insertions(+), 65 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 5162d55..310a1af 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -45,6 +45,10 @@
 
 #ifdef USE_KQEMU
 
+#define KQEMU_USER 1
+#define KQEMU_KERNEL 2
+
+static int kqemu_state;
 #define DEBUG
 //#define PROFILE
 
@@ -75,11 +79,6 @@ int kqemu_fd = KQEMU_INVALID_FD;
 #define kqemu_closefd(x) close(x)
 #endif
 
-/* 0 = not allowed
-   1 = user kqemu
-   2 = kernel kqemu
-*/
-int kqemu_allowed = 1;
 uint64_t *pages_to_flush;
 unsigned int nb_pages_to_flush;
 uint64_t *ram_pages_to_update;
@@ -131,20 +130,12 @@ static int is_cpuid_supported(void)
  */
 int kqemu_is_enabled(CPUState *env)
 {
-    if (strcasecmp(current_accel->name, "kqemu")) {
-        return 0;
-    }
-
-    return env->kqemu_enabled;
-
+    return kqemu_state == KQEMU_USER;
 }
 
 int kqemu_kernel_enabled(CPUState *env)
 {
-    if (strcasecmp(current_accel->name, "kqemu")) {
-        return 0;
-    }
-    return env->kqemu_enabled == 2;
+    return kqemu_state == KQEMU_KERNEL;
 }
 
 static void kqemu_update_cpuid(CPUState *env)
@@ -186,7 +177,7 @@ static void kqemu_update_cpuid(CPUState *env)
 
 QEMUAccel kqemu_accel;
 
-static int kqemu_start(int cpus)
+static int kqemu_do_start(int cpus)
 {
     struct kqemu_init kinit;
     int ret, version;
@@ -194,7 +185,7 @@ static int kqemu_start(int cpus)
     DWORD temp;
 #endif
 
-    if (!kqemu_allowed || cpus > 1)
+    if (cpus > 1)
         return -1;
 
 #ifdef _WIN32
@@ -273,10 +264,28 @@ static int kqemu_start(int cpus)
     return 0;
 }
 
+static int kqemu_start(int cpus)
+{
+    kqemu_state = KQEMU_USER;
+    return kqemu_do_start(cpus);
+}
+
+static int kqemu_start_kernel(int cpus)
+{
+    kqemu_state = KQEMU_KERNEL;
+    return kqemu_do_start(cpus);
+}
+
 static void kqemu_init_env(CPUState *env)
 {
     kqemu_update_cpuid(env);
-    env->kqemu_enabled = kqemu_allowed;
+    env->kqemu_enabled = 1;
+}
+
+static void kqemu_init_env_kernel(CPUState *env)
+{
+    kqemu_update_cpuid(env);
+    env->kqemu_enabled = 2;
 }
 
 static void kqemu_flush_page(CPUState *env, target_ulong addr)
@@ -791,7 +800,7 @@ static int kqemu_do_cpu_exec(CPUState *env)
     cpl = (env->hflags & HF_CPL_MASK);
     kenv->cpl = cpl;
     kenv->nb_pages_to_flush = nb_pages_to_flush;
-    kenv->user_only = (env->kqemu_enabled == 1);
+    kenv->user_only = kqemu_is_enabled(env);
     kenv->nb_ram_pages_to_update = nb_ram_pages_to_update;
     nb_ram_pages_to_update = 0;
     kenv->nb_modified_ram_pages = nb_modified_ram_pages;
@@ -1082,27 +1091,12 @@ static void qpi_init(void)
 
 static int kqemu_info(CPUState *env, char *buf)
 {
-    int val, len;
-    int bufsiz = MAX_INFO_BUF;
-    val = 0;
-    val = env->kqemu_enabled;
-    len = snprintf(buf, bufsiz, "kqemu support: ");
-    buf += len;
-    bufsiz -= len;
-
-    switch(val) {
-    default:
-        len += snprintf(buf, bufsiz, "present, but bogus value\n");
-        break;
-    case 1:
-        len += snprintf(buf, bufsiz, "enabled for user code\n");
-        break;
-    case 2:
-        len += snprintf(buf, bufsiz, "enabled for user and kernel code\n");
-        break;
-    }
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user code\n");
+}
 
-    return len;
+static int kqemu_kernel_info(CPUState *env, char *buf)
+{
+    return snprintf(buf, MAX_INFO_BUF, "kqemu support: enabled for user and kernel code\n");
 }
 
 int64_t kqemu_time;
@@ -1141,10 +1135,27 @@ static void kqemu_trace_io(CPUState *env)
         kqemu_cpu_field(env,last_io_time) = cpu_get_time_fast();
 }
 
+#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
+
+static inline int kqemu_flags_ok(CPUState *env)
+{
+    return((env->cr[0] & CR0_PE_MASK) &&
+           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
+           (env->eflags & IF_MASK) &&
+           !(env->eflags & VM_MASK));
+}
+
+static inline int kqemu_kernel_flags_ok(CPUState *env)
+{
+    return (kqemu_flags_ok(env) && (kqemu_kernel_enabled(env) ||
+            ((env->hflags & HF_CPL_MASK) == 3 &&
+             (env->eflags & IOPL_MASK) != IOPL_MASK)));
+
+}
+
 static int kqemu_break_loop(CPUState *env)
 {
-#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
-    if (kqemu_is_ok(env) &&
+    if (kqemu_kernel_flags_ok(env) &&
         (cpu_get_time_fast() - kqemu_cpu_field(env,last_io_time)) >= MIN_CYCLE_BEFORE_SWITCH) {
         return 1;
     }
@@ -1182,4 +1193,25 @@ QEMUAccel kqemu_accel = {
     .cpu_exec = kqemu_cpu_exec,
 };
 
+QEMUAccel kqemu_kernel_accel = {
+    .name = "kernel-KQEMU",
+    .cpu_interrupt = kqemu_cpu_interrupt,
+    .init_env = kqemu_init_env_kernel,
+    .get_env = kqemu_get_env,
+    .start = kqemu_start_kernel,
+    .flush_cache = kqemu_flush,
+    .flush_page = kqemu_flush_page,
+    .info = kqemu_kernel_info,
+    .profile = kqemu_profile,
+    .set_notdirty = kqemu_set_notdirty,
+    .modify_page = kqemu_modify_page,
+#ifndef CONFIG_USER_ONLY
+    .get_real_ticks = cpu_get_real_ticks,
+#endif
+    .register_physical_memory = kqemu_set_phys_mem,
+    .trace_io = kqemu_trace_io,
+    .break_loop = kqemu_break_loop,
+    .cpu_exec = kqemu_cpu_exec,
+};
+
 #endif
diff --git a/kqemu.h b/kqemu.h
index 62ba1d9..f644e41 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -161,7 +161,6 @@ int kqemu_is_enabled(CPUState *env);
 int kqemu_kernel_enabled(CPUState *env);
 
 typedef struct KQEMUCPUstate {
-    int kqemu_enabled;
     int last_io_time;
     CPUState env;
 } KQEMUCPUState;
diff --git a/sysemu.h b/sysemu.h
index 976fecc..5a19626 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -99,11 +99,6 @@ extern int semihosting_enabled;
 extern int old_param;
 extern const char *bootp_filename;
 
-
-#ifdef USE_KQEMU
-extern int kqemu_allowed;
-#endif
-
 #define MAX_OPTION_ROMS 16
 extern const char *option_rom[MAX_OPTION_ROMS];
 extern int nb_option_roms;
diff --git a/vl.c b/vl.c
index e64becb..42720e8 100644
--- a/vl.c
+++ b/vl.c
@@ -259,6 +259,7 @@ QEMUAccel *available_accels[] = {
 /* list of available accelerators */
 #ifdef USE_KQEMU
     &kqemu_accel,
+    &kqemu_kernel_accel,
 #endif
 };
 
@@ -8236,10 +8237,6 @@ static void help(int exitcode)
            "-hdachs c,h,s[,t]  force hard disk 0 physical geometry and the optional BIOS\n"
            "                translation (t=none or lba) (usually qemu can guess them)\n"
            "-L path         set the directory for the BIOS, VGA BIOS and keymaps\n"
-#ifdef USE_KQEMU
-           "-kernel-kqemu   enable KQEMU full virtualization (default is user mode only)\n"
-           "-no-kqemu       disable KQEMU kernel module usage\n"
-#endif
 #ifdef TARGET_I386
            "-no-acpi        disable ACPI\n"
 #endif
@@ -8343,9 +8340,7 @@ enum {
     QEMU_OPTION_alt_grab,
     QEMU_OPTION_no_quit,
     QEMU_OPTION_pidfile,
-    QEMU_OPTION_no_kqemu,
     QEMU_OPTION_accel,
-    QEMU_OPTION_kernel_kqemu,
     QEMU_OPTION_win2k_hack,
     QEMU_OPTION_usb,
     QEMU_OPTION_usbdevice,
@@ -8428,10 +8423,6 @@ static const QEMUOption qemu_options[] = {
     { "hdachs", HAS_ARG, QEMU_OPTION_hdachs },
     { "L", HAS_ARG, QEMU_OPTION_L },
     { "bios", HAS_ARG, QEMU_OPTION_bios },
-#ifdef USE_KQEMU
-    { "no-kqemu", 0, QEMU_OPTION_no_kqemu },
-    { "kernel-kqemu", 0, QEMU_OPTION_kernel_kqemu },
-#endif
     { "accel", HAS_ARG, QEMU_OPTION_accel},
 #if defined(TARGET_PPC) || defined(TARGET_SPARC)
     { "g", 1, QEMU_OPTION_g },
@@ -9247,14 +9238,6 @@ int main(int argc, char **argv)
                 win2k_install_hack = 1;
                 break;
 #endif
-#ifdef USE_KQEMU
-            case QEMU_OPTION_no_kqemu:
-                kqemu_allowed = 0;
-                break;
-            case QEMU_OPTION_kernel_kqemu:
-                kqemu_allowed = 2;
-                break;
-#endif
             case QEMU_OPTION_accel:
                 {
                     int i;
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (27 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 26/32] provide two accelerators for kqemu Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 13:30   ` [Qemu-devel] " Avi Kivity
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 28/32] iret arch specific accelerator Glauber Costa
                   ` (4 subsequent siblings)
  33 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

This patch provides an arch field in QEMUAccel. It will
be used initially for x86, to replace kqemu code in op_helper.c
We start with get_msr and set_msr functions, that allow accelerators
to handle non-default msrs.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 accel.h                 |    1 +
 exec-all.h              |    2 --
 kqemu.c                 |   26 +++++++++++++++++++++++++-
 target-i386/accel86.h   |   28 ++++++++++++++++++++++++++++
 target-i386/op_helper.c |   14 +++-----------
 5 files changed, 57 insertions(+), 14 deletions(-)
 create mode 100644 target-i386/accel86.h

diff --git a/accel.h b/accel.h
index 1741f06..00a495c 100644
--- a/accel.h
+++ b/accel.h
@@ -23,6 +23,7 @@ typedef struct QEMUAccel {
     void (*trace_io)(CPUState *env);
     int (*break_loop)(CPUState *env);
     int (*cpu_exec)(CPUState *env);
+    void *arch; /* arch-specific accel functions */
 } QEMUAccel;
 
 typedef struct QEMUCont {
diff --git a/exec-all.h b/exec-all.h
index 8228746..1e9aa5a 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -369,8 +369,6 @@ void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size,
                         ram_addr_t phys_offset);
 void kqemu_record_dump(void);
 
-extern uint32_t kqemu_comm_base;
-
 static inline int kqemu_is_ok(CPUState *env)
 {
     return(env->kqemu_enabled &&
diff --git a/kqemu.c b/kqemu.c
index 310a1af..cab6354 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -55,7 +55,7 @@ static int kqemu_state;
 #include <unistd.h>
 #include <fcntl.h>
 #include "kqemu.h"
-#include "accel.h"
+#include "accel86.h"
 
 #ifdef CONFIG_PROFILER
 #include "qemu-timer.h" /* for ticks_per_sec */
@@ -1169,6 +1169,28 @@ static CPUState *kqemu_get_env(void)
     return &kenv->env;
 }
 
+static int kqemu_get_msr(int msr, uint64_t *val)
+{
+    int ret = -1;
+    switch (msr) {
+    case MSR_QPI_COMMBASE:
+        val = kqemu_comm_base;
+        ret = 0;
+        break;
+    }
+    return ret;
+}
+
+static int kqemu_set_msr(int msr, target_ulong val)
+{
+    return -1;
+}
+
+QEMUAccel86 kqemu_accel86 = {
+    .get_msr = kqemu_get_msr,
+    .set_msr = kqemu_set_msr,
+};
+
 QEMUAccel kqemu_accel = {
     .name = "KQEMU",
     .cpu_interrupt = kqemu_cpu_interrupt,
@@ -1191,6 +1213,7 @@ QEMUAccel kqemu_accel = {
     .trace_io = kqemu_trace_io,
     .break_loop = kqemu_break_loop,
     .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
 };
 
 QEMUAccel kqemu_kernel_accel = {
@@ -1212,6 +1235,7 @@ QEMUAccel kqemu_kernel_accel = {
     .trace_io = kqemu_trace_io,
     .break_loop = kqemu_break_loop,
     .cpu_exec = kqemu_cpu_exec,
+    .arch = &kqemu_accel86,
 };
 
 #endif
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
new file mode 100644
index 0000000..142d63e
--- /dev/null
+++ b/target-i386/accel86.h
@@ -0,0 +1,28 @@
+#ifndef _ACCEL_86_H_
+#define _ACCEL_86_H_
+
+#include "accel.h"
+
+typedef struct QEMUAccel86 {
+	int (*get_msr)(int msr, uint64_t *value);
+	int (*set_msr)(int msr, uint64_t value);
+} QEMUAccel86;
+
+#define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
+
+static inline int accel_get_msr(int msr, uint64_t *value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->get_msr(msr, value);
+}
+
+static inline int accel_set_msr(int msr, uint64_t value)
+{
+    if (!current_accel->arch)
+        return -1;
+    return accel86_call_func->set_msr(msr, value);
+}
+
+#endif
+
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index ebb5824..fe8ddf8 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -20,6 +20,7 @@
 #define CPU_NO_GLOBAL_REGS
 #include "exec.h"
 #include "host-utils.h"
+#include "accel86.h"
 
 //#define DEBUG_PCALL
 
@@ -3262,18 +3263,9 @@ void helper_rdmsr(void)
         val = env->kernelgsbase;
         break;
 #endif
-#ifdef USE_KQEMU
-    case MSR_QPI_COMMBASE:
-        if (env->kqemu_enabled) {
-            val = kqemu_comm_base;
-        } else {
-            val = 0;
-        }
-        break;
-#endif
     default:
-        /* XXX: exception ? */
-        val = 0;
+        if (accel_get_msr((uint32_t)ECX, &val) < 0)
+            val = 0;
         break;
     }
     EAX = (uint32_t)(val);
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 28/32] iret arch specific accelerator
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (28 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 29/32] sysret/sysexit " Glauber Costa
                   ` (3 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

let arch-specific accelerator hook into the end of interrupt
return.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c                 |   10 ++++++++++
 target-i386/accel86.h   |    8 ++++++++
 target-i386/op_helper.c |    9 ++-------
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index cab6354..0bea20e 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1186,9 +1186,19 @@ static int kqemu_set_msr(int msr, target_ulong val)
     return -1;
 }
 
+static void kqemu_interrupt_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
 QEMUAccel86 kqemu_accel86 = {
     .get_msr = kqemu_get_msr,
     .set_msr = kqemu_set_msr,
+    .interrupt_return = kqemu_interrupt_return,
 };
 
 QEMUAccel kqemu_accel = {
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
index 142d63e..c3201f5 100644
--- a/target-i386/accel86.h
+++ b/target-i386/accel86.h
@@ -6,6 +6,7 @@
 typedef struct QEMUAccel86 {
 	int (*get_msr)(int msr, uint64_t *value);
 	int (*set_msr)(int msr, uint64_t value);
+    void (*interrupt_return)(CPUState *env);
 } QEMUAccel86;
 
 #define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
@@ -24,5 +25,12 @@ static inline int accel_set_msr(int msr, uint64_t value)
     return accel86_call_func->set_msr(msr, value);
 }
 
+static inline void accel_interrupt_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->interrupt_return(env);
+}
+
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index fe8ddf8..61ba6fc 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -2918,13 +2918,8 @@ void helper_iret_protected(int shift, int next_eip)
         helper_ret_protected(shift, 1, 0);
     }
     env->hflags2 &= ~HF2_NMI_MASK;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+
+    accel_interrupt_return(env);
 }
 
 void helper_lret_protected(int shift, int addend)
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 29/32] sysret/sysexit arch specific accelerator
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (29 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 28/32] iret arch specific accelerator Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 30/32] lcall/lret arch specific accel hooks Glauber Costa
                   ` (2 subsequent siblings)
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

let arch-specific accelerator hook into the end of syscall
return functions sysret and sysexit.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c                 |   11 +++++++++++
 target-i386/accel86.h   |    8 ++++++++
 target-i386/op_helper.c |   15 +--------------
 3 files changed, 20 insertions(+), 14 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 0bea20e..1934aa5 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1195,10 +1195,21 @@ static void kqemu_interrupt_return(CPUState *env)
     }
 }
 
+static void kqemu_syscall_return(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        if (env->hflags & HF_LMA_MASK)
+            CC_OP = CC_OP_EFLAGS;
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
 QEMUAccel86 kqemu_accel86 = {
     .get_msr = kqemu_get_msr,
     .set_msr = kqemu_set_msr,
     .interrupt_return = kqemu_interrupt_return,
+    .syscall_return = kqemu_syscall_return,
 };
 
 QEMUAccel kqemu_accel = {
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
index c3201f5..1624a64 100644
--- a/target-i386/accel86.h
+++ b/target-i386/accel86.h
@@ -7,6 +7,7 @@ typedef struct QEMUAccel86 {
 	int (*get_msr)(int msr, uint64_t *value);
 	int (*set_msr)(int msr, uint64_t value);
     void (*interrupt_return)(CPUState *env);
+    void (*syscall_return)(CPUState *env);
 } QEMUAccel86;
 
 #define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
@@ -32,5 +33,12 @@ static inline void accel_interrupt_return(CPUState *env)
     accel86_call_func->interrupt_return(env);
 }
 
+static inline void accel_syscall_return(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index 61ba6fc..a831a4d 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -1104,14 +1104,7 @@ void helper_sysret(int dflag)
         env->eflags |= IF_MASK;
         cpu_x86_set_cpl(env, 3);
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        if (env->hflags & HF_LMA_MASK)
-            CC_OP = CC_OP_EFLAGS;
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_syscall_return(env);
 }
 
 /* real mode interrupt */
@@ -3003,12 +2996,6 @@ void helper_sysexit(int dflag)
     }
     ESP = ECX;
     EIP = EDX;
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
 }
 
 #if defined(CONFIG_USER_ONLY)
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 30/32] lcall/lret arch specific accel hooks
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (30 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 29/32] sysret/sysexit " Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 31/32] remove kqemu_is_ok tests Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 32/32] clean up kqemu code Glauber Costa
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

provide arch specific hooks for far calls in op_helper.c

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 kqemu.c                 |   10 ++++++++++
 target-i386/accel86.h   |   16 ++++++++++++++++
 target-i386/op_helper.c |   14 ++------------
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/kqemu.c b/kqemu.c
index 1934aa5..7b87a58 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -1205,11 +1205,21 @@ static void kqemu_syscall_return(CPUState *env)
     }
 }
 
+static void kqemu_long_exit_loop(CPUState *env)
+{
+    if (kqemu_kernel_flags_ok(env)) {
+        env->exception_index = -1;
+        cpu_loop_exit();
+    }
+}
+
 QEMUAccel86 kqemu_accel86 = {
     .get_msr = kqemu_get_msr,
     .set_msr = kqemu_set_msr,
     .interrupt_return = kqemu_interrupt_return,
     .syscall_return = kqemu_syscall_return,
+    .long_call = kqemu_long_exit_loop,
+    .long_ret = kqemu_long_exit_loop,
 };
 
 QEMUAccel kqemu_accel = {
diff --git a/target-i386/accel86.h b/target-i386/accel86.h
index 1624a64..a7ba39b 100644
--- a/target-i386/accel86.h
+++ b/target-i386/accel86.h
@@ -8,6 +8,8 @@ typedef struct QEMUAccel86 {
 	int (*set_msr)(int msr, uint64_t value);
     void (*interrupt_return)(CPUState *env);
     void (*syscall_return)(CPUState *env);
+    void (*long_call)(CPUState *env);
+    void (*long_ret)(CPUState *env);
 } QEMUAccel86;
 
 #define accel86_call_func ((QEMUAccel86 *)(current_accel->arch))
@@ -40,5 +42,19 @@ static inline void accel_syscall_return(CPUState *env)
     accel86_call_func->syscall_return(env);
 }
 
+static inline void accel_long_call(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
+static inline void accel_long_ret(CPUState *env)
+{
+    if (!current_accel->arch)
+        return;
+    accel86_call_func->syscall_return(env);
+}
+
 #endif
 
diff --git a/target-i386/op_helper.c b/target-i386/op_helper.c
index a831a4d..addd42a 100644
--- a/target-i386/op_helper.c
+++ b/target-i386/op_helper.c
@@ -2617,12 +2617,7 @@ void helper_lcall_protected(int new_cs, target_ulong new_eip,
         SET_ESP(sp, sp_mask);
         EIP = offset;
     }
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_call(env);
 }
 
 /* real and vm86 mode iret */
@@ -2918,12 +2913,7 @@ void helper_iret_protected(int shift, int next_eip)
 void helper_lret_protected(int shift, int addend)
 {
     helper_ret_protected(shift, 0, addend);
-#ifdef USE_KQEMU
-    if (kqemu_is_ok(env)) {
-        env->exception_index = -1;
-        cpu_loop_exit();
-    }
-#endif
+    accel_long_ret(env);
 }
 
 void helper_sysenter(void)
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 31/32] remove kqemu_is_ok tests.
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (31 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 30/32] lcall/lret arch specific accel hooks Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 32/32] clean up kqemu code Glauber Costa
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Replace kqemu_is_ok with local tests, since they it is not
used anywhere else in the code.

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 exec-all.h        |   12 ------------
 kqemu.c           |   11 ++---------
 target-i386/cpu.h |    3 ---
 3 files changed, 2 insertions(+), 24 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 1e9aa5a..55972ac 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -369,17 +369,5 @@ void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size,
                         ram_addr_t phys_offset);
 void kqemu_record_dump(void);
 
-static inline int kqemu_is_ok(CPUState *env)
-{
-    return(env->kqemu_enabled &&
-           (env->cr[0] & CR0_PE_MASK) &&
-           !(env->hflags & HF_INHIBIT_IRQ_MASK) &&
-           (env->eflags & IF_MASK) &&
-           !(env->eflags & VM_MASK) &&
-           (env->kqemu_enabled == 2 ||
-            ((env->hflags & HF_CPL_MASK) == 3 &&
-             (env->eflags & IOPL_MASK) != IOPL_MASK)));
-}
-
 #endif
 #endif
diff --git a/kqemu.c b/kqemu.c
index 7b87a58..58a149b 100644
--- a/kqemu.c
+++ b/kqemu.c
@@ -279,13 +279,6 @@ static int kqemu_start_kernel(int cpus)
 static void kqemu_init_env(CPUState *env)
 {
     kqemu_update_cpuid(env);
-    env->kqemu_enabled = 1;
-}
-
-static void kqemu_init_env_kernel(CPUState *env)
-{
-    kqemu_update_cpuid(env);
-    env->kqemu_enabled = 2;
 }
 
 static void kqemu_flush_page(CPUState *env, target_ulong addr)
@@ -994,7 +987,7 @@ static int kqemu_cpu_exec(CPUState *env)
 {
 
     int ret = EXEC_EXIT_SOFTMMU;
-    if (kqemu_is_ok(env) && env->interrupt_request == 0) {
+    if (kqemu_kernel_flags_ok(env) && env->interrupt_request == 0) {
         ret = kqemu_do_cpu_exec(env);
         /* put eflags in CPU temporary format */
         CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
@@ -1250,7 +1243,7 @@ QEMUAccel kqemu_accel = {
 QEMUAccel kqemu_kernel_accel = {
     .name = "kernel-KQEMU",
     .cpu_interrupt = kqemu_cpu_interrupt,
-    .init_env = kqemu_init_env_kernel,
+    .init_env = kqemu_init_env,
     .get_env = kqemu_get_env,
     .start = kqemu_start_kernel,
     .flush_cache = kqemu_flush,
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 6310529..e5e91cc 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -606,9 +606,6 @@ typedef struct CPUX86State {
     uint32_t cpuid_ext3_features;
     uint32_t cpuid_apic_id;
 
-#ifdef USE_KQEMU
-    int kqemu_enabled;
-#endif
     /* in order to simplify APIC support, we leave this pointer to the
        user */
     struct APICState *apic_state;
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] [PATCH 32/32] clean up kqemu code
  2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
                   ` (32 preceding siblings ...)
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 31/32] remove kqemu_is_ok tests Glauber Costa
@ 2008-10-23 14:19 ` Glauber Costa
  33 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: jan.kiszka, aliguori, jes, avi, dmitry.baryshkov

Remove bits from kqemu.h that are no longer used outside of
kqemu files scope. The ones which are still needed are moved to
kqemu.h

Signed-off-by: Glauber Costa <glommer@redhat.com>
---
 exec-all.h |   10 ----------
 kqemu.h    |    3 +++
 2 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/exec-all.h b/exec-all.h
index 55972ac..fa4a4eb 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -360,14 +360,4 @@ static inline int can_do_io(CPUState *env)
 #define EXEC_EXIT_INTR 1
 #define EXEC_EXIT_SOFTMMU 2
 
-#ifdef USE_KQEMU
-#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
-
-#define MSR_QPI_COMMBASE 0xfabe0010
-
-void kqemu_set_phys_mem(uint64_t start_addr, ram_addr_t size, 
-                        ram_addr_t phys_offset);
-void kqemu_record_dump(void);
-
-#endif
 #endif
diff --git a/kqemu.h b/kqemu.h
index f644e41..4152fbd 100644
--- a/kqemu.h
+++ b/kqemu.h
@@ -169,4 +169,7 @@ typedef struct KQEMUCPUstate {
     KQEMUCPUState *__c = container_of(env, KQEMUCPUState, env); \
     &__c->field; }))
 
+#define KQEMU_MODIFY_PAGE_MASK (0xff & ~(VGA_DIRTY_FLAG | CODE_DIRTY_FLAG))
+
+#define MSR_QPI_COMMBASE 0xfabe0010
 #endif /* KQEMU_H */
-- 
1.5.5.1

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 20/32] accel_trace_io
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
@ 2008-10-23 14:20   ` Anthony Liguori
  2008-10-23 17:26     ` Glauber de Oliveira Costa
  2008-10-25 11:10   ` [Qemu-devel] " andrzej zaborowski
  1 sibling, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:20 UTC (permalink / raw)
  To: Glauber Costa
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> kqemu keeps trace of the last io done. Do it through
> an accel_wrapper.
>   

The hooks here are probably not the best they could be.  The purpose of 
this code in kqemu, from what I can tell, is to control how long we run 
in softmmu before trying to run in the kernel again.  I presume this is 
mainly for kernel-kqemu.

When kernel-kqemu encounters an instruction it can't handle, it drops to 
userspace and runs in softmmu for a while.  The question is how long 
should it run in softmmu and this is a heuristic.  This is what the code 
is doing.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 04/32] move kqemu_cpu_exec to kqemu.c
  2008-10-23 13:55   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:21     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:21 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 08:55:14AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> Only pieces of code that are frame-safe can be moved.
>> compute_all() is an example of a non-frame-safe calling.
>> So it has to be done prior to calling kqemu_cpu_exec().
>>
>> Signed-off-by: Glauber Costa <glommer@redhat.com>
>> ---
>>  cpu-exec.c |   33 +++++++++++++--------------------
>>  kqemu.c    |   18 +++++++++++++++++-
>>  2 files changed, 30 insertions(+), 21 deletions(-)
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index 6d4dcdd..f06df26 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -336,27 +336,20 @@ int cpu_exec(CPUState *env1)
>>                  env->exception_index = -1;
>>              }
>>  #ifdef USE_KQEMU
>> -            if (kqemu_is_ok(env) && env->interrupt_request == 0) {
>> -                int ret;
>> -                env->eflags = env->eflags | cc_table[CC_OP].compute_all() | (DF & DF_MASK);
>> -                ret = kqemu_cpu_exec(env);
>> -                /* put eflags in CPU temporary format */
>> -                CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>> -                DF = 1 - (2 * ((env->eflags >> 10) & 1));
>> -                CC_OP = CC_OP_EFLAGS;
>> -                env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>> -                if (ret == 1) {
>> -                    /* exception */
>> -                    longjmp(env->jmp_env, 1);
>> -                } else if (ret == 2) {
>> -                    /* softmmu execution needed */
>> +            env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
>>   
>
> Can't do this unconditionally since you're now recomputing all condition  
> flags even when kqemu is not in use.  So unfortunately I'm not sure the  
> code can be cleaned up much more if compute_all() must stay in cpu_exec.
>
> Regards,
We can add an auxiliary function into the accel structure in which the accelerator indicates
whether or not it needs the condition flags to be recomputed.

But, in general, I'm fine with not touching it, since kvm io thread's implementation
does not rely on this code path. Don't know about xen or any other interested parties, tough.

>
> Anthony Liguori
>
>> +            ret = kqemu_cpu_exec(env);
>> +            env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>> +            if (ret == 1) {
>> +                /* exception */
>> +                longjmp(env->jmp_env, 1);
>> +            } else if (ret == 2) {
>> +                /* softmmu execution needed */
>> +            } else {
>> +                if (env->interrupt_request != 0) {
>> +                    /* hardware interrupt will be executed just after */
>>                  } else {
>> -                    if (env->interrupt_request != 0) {
>> -                        /* hardware interrupt will be executed just after */
>> -                    } else {
>> -                        /* otherwise, we restart */
>> -                        longjmp(env->jmp_env, 1);
>> -                    }
>> +                    /* otherwise, we restart */
>> +                    longjmp(env->jmp_env, 1);
>>                  }
>>              }
>>  #endif
>> diff --git a/kqemu.c b/kqemu.c
>> index 4783aa2..39938e0 100644
>> --- a/kqemu.c
>> +++ b/kqemu.c
>> @@ -30,6 +30,7 @@
>>  #ifdef HOST_SOLARIS
>>  #include <sys/ioccom.h>
>>  #endif
>> +#include "exec.h"
>>  #include <stdlib.h>
>>  #include <stdio.h>
>>  #include <stdarg.h>
>> @@ -689,7 +690,7 @@ static inline void kqemu_save_seg(SegmentCache *sc,
>>      sc->base = ksc->base;
>>  }
>>
>> -int kqemu_cpu_exec(CPUState *env)
>> +int kqemu_do_cpu_exec(CPUState *env)
>>  {
>>      struct kqemu_cpu_state kcpu_state, *kenv = &kcpu_state;
>>      int ret, cpl, i;
>> @@ -939,6 +940,21 @@ int kqemu_cpu_exec(CPUState *env)
>>      return 0;
>>  }
>>
>> +int kqemu_cpu_exec(CPUState *env)
>> +{
>> +
>> +    int ret = 2;
>> +    if (kqemu_is_ok(env) && env->interrupt_request == 0) {
>> +        ret = kqemu_do_cpu_exec(env);
>> +        /* put eflags in CPU temporary format */
>> +        CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>> +        DF = 1 - (2 * ((env->eflags >> 10) & 1));
>> +        CC_OP = CC_OP_EFLAGS;
>> +    }
>> +    return ret;
>> +}
>> +
>> +
>>  void kqemu_cpu_interrupt(CPUState *env)
>>  {
>>  #if defined(_WIN32)
>>   
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 22/32] add next_cpu_index
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 22/32] add next_cpu_index Glauber Costa
@ 2008-10-23 14:21   ` Anthony Liguori
  2008-10-23 14:37     ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:21 UTC (permalink / raw)
  To: Glauber Costa
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

Glauber Costa wrote:
> From: Glauber Costa <gcosta@redhat.com>
>
> separate the logic for calculating the next cpu index
> from cpu creation. It will allow others to query what's
> the next cpu index to be created before cpu creation.
>   

What is this useful for?

Regards,

Anthony Liguori

> Signed-off-by: Glauber Costa <gcosta@redhat.com>
> ---
>  exec.c |   22 ++++++++++++++--------
>  1 files changed, 14 insertions(+), 8 deletions(-)
>
> diff --git a/exec.c b/exec.c
> index 80b8a78..7fe7eeb 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -526,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
>  }
>  #endif
>
> -void cpu_exec_init(CPUState *env)
> +int next_cpu_index(void)
>  {
>      CPUState **penv;
> -    int cpu_index;
> +    int cpu_index = 0;
>
> -    env->next_cpu = NULL;
>      penv = &first_cpu;
> -    cpu_index = 0;
> +
>      while (*penv != NULL) {
>          penv = (CPUState **)&(*penv)->next_cpu;
>          cpu_index++;
>      }
> -    env->cpu_index = cpu_index;
> +    return cpu_index;
> +}
> +
> +void cpu_exec_init(CPUState *env)
> +{
> +    env->next_cpu = NULL;
> +    env->cpu_index = next_cpu_index();
>      env->nb_watchpoints = 0;
> -    *penv = env;
> +    if (env->cpu_index == 0)
> +        first_cpu = env;
>  #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
> -    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
> +    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
>                      cpu_common_save, cpu_common_load, env);
> -    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
> +    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
>                      cpu_save, cpu_load, env);
>  #endif
>  }
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 05/32] use more meaningful values for kqemu_cpu_exec
  2008-10-23 13:57   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:23     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:23 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 08:57:21AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> define constants that actually mean something instead of 1, 2, etc
>>
>> Signed-off-by: Glauber Costa <glommer@redhat.com>
>> ---
>>  cpu-exec.c |    4 ++--
>>  exec-all.h |    4 ++++
>>  kqemu.c    |   12 ++++++------
>>  3 files changed, 12 insertions(+), 8 deletions(-)
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index f06df26..88b7d6f 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -339,10 +339,10 @@ int cpu_exec(CPUState *env1)
>>              env->eflags = env->eflags | cc_table[CC_OP].compute_all()  | (DF & DF_MASK);
>>              ret = kqemu_cpu_exec(env);
>>              env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
>> -            if (ret == 1) {
>> +            if (ret == EXEC_EXIT_INTR) {
>>                  /* exception */
>>                  longjmp(env->jmp_env, 1);
>> -            } else if (ret == 2) {
>> +            } else if (ret == EXEC_EXIT_SOFTMMU) {
>>                  /* softmmu execution needed */
>>              } else {
>>                  if (env->interrupt_request != 0) {
>> diff --git a/exec-all.h b/exec-all.h
>> index e3da98a..c10248b 100644
>> --- a/exec-all.h
>> +++ b/exec-all.h
>> @@ -356,6 +356,10 @@ static inline int can_do_io(CPUState *env)
>>  }
>>  #endif
>>
>> +#define EXEC_EXIT_DONE 0
>> +#define EXEC_EXIT_INTR 1
>> +#define EXEC_EXIT_SOFTMMU 2
>> +
>>   
>
> How about ACCEL_EXIT_?  These codes are accelerator specific after all.
I believe ACCEL_EXIT is confusing. ACCEL_EXEC_EXIT would be better, since
it makes it clear that it is used in exec context. However, if we're droping
the cpu_exec patch, we can drop this one too.

>
> Regards,
>
> Anthony Liguori
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 24/32] check wether kqemu is enabled in open code
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
  2008-10-23 13:38   ` [Qemu-devel] " Jan Kiszka
@ 2008-10-23 14:23   ` Anthony Liguori
  2008-10-23 14:31     ` Glauber Costa
  1 sibling, 1 reply; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:23 UTC (permalink / raw)
  To: Glauber Costa; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

Glauber Costa wrote:
> kqemu is still too much spread around. The proper fix
> usually involves rethinking a bit of kqemu logic so for now,
> just check whether or not kqemu is enabled. If the kqemu accelerator
> is not present, consider it not. Otherwise, check env field.
>
> Signed-off-by: Glauber Costa <glommer@redhat.com>
> ---
>  cpu-exec.c |    2 +-
>  kqemu.c    |   21 +++++++++++++++++++++
>  kqemu.h    |    3 +++
>  3 files changed, 25 insertions(+), 1 deletions(-)
>
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 18908d5..b47cf43 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
>                  {
>                      if (next_tb != 0 &&
>  #ifdef USE_KQEMU
> -                        (env->kqemu_enabled != 2) &&
> +                        (!kqemu_kernel_enabled(env)) &&
>  #endif
>                          tb->page_addr[1] == -1) {
>                      tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
> diff --git a/kqemu.c b/kqemu.c
> index 16ebe7d..f99a4f1 100644
> --- a/kqemu.c
> +++ b/kqemu.c
> @@ -126,6 +126,27 @@ static int is_cpuid_supported(void)
>  }
>  #endif
>
> +/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
> + * altogether
> + */
> +int kqemu_is_enabled(CPUState *env)
> +{
> +    if (strcasecmp(current_accel->name, "kqemu")) {
> +        return 0;
> +    }
> +
> +    return env->kqemu_enabled;
> +
> +}
> +
> +int kqemu_kernel_enabled(CPUState *env)
> +{
> +    if (strcasecmp(current_accel->name, "kqemu")) {
> +        return 0;
> +    }
> +    return env->kqemu_enabled == 2;
> +}
>   

Why is kqemu_enabled part of the vcpu state?  Wouldn't it always be 0 
even if we weren't using the accelerator?

Regards,

Anthony Liguori

>  static void kqemu_update_cpuid(CPUState *env)
>  {
>      int critical_features_mask, features, ext_features, ext_features_mask;
> diff --git a/kqemu.h b/kqemu.h
> index cf14179..62ba1d9 100644
> --- a/kqemu.h
> +++ b/kqemu.h
> @@ -157,6 +157,9 @@ struct kqemu_phys_mem {
>  #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
>  #endif
>
> +int kqemu_is_enabled(CPUState *env);
> +int kqemu_kernel_enabled(CPUState *env);
> +
>  typedef struct KQEMUCPUstate {
>      int kqemu_enabled;
>      int last_io_time;
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 10/32] turn info kqemu into generic info accelerator
  2008-10-23 14:03   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:24     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:24 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

On Thu, Oct 23, 2008 at 09:03:45AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> From: Glauber Costa <gcosta@redhat.com>
>>
>> Yet another accel field: info.
>> From this point on, "info kqemu" is no more. "info accelerator" should
>> be used instead.
>>
>> Signed-off-by: Glauber Costa <glommer@redhat.com>
>> ---
>>  accel.c   |    6 ++++++
>>  accel.h   |    8 ++++++++
>>  kqemu.c   |   26 ++++++++++++++++++++++++++
>>  monitor.c |   35 ++++++++++++-----------------------
>>  4 files changed, 52 insertions(+), 23 deletions(-)
>>
>> diff --git a/accel.c b/accel.c
>> index 6776244..cb615d7 100644
>> --- a/accel.c
>> +++ b/accel.c
>> @@ -8,6 +8,11 @@ int _accel_nop(void)
>>      return 0;
>>  }
>>
>> +int noaccel_info(CPUState *env, char *buf)
>> +{
>> +    return snprintf(buf, MAX_INFO_BUF, "no accelerator present.\n");
>> +}
>> +
>>  #define accel_nop ((void *)_accel_nop)
>>
>>  /* Accelerator wrapper for the no-accel (raw qemu) case */
>> @@ -16,5 +21,6 @@ QEMUAccel noaccel = {
>>      .init_env = accel_nop,
>>      .flush_cache = accel_nop,
>>      .flush_page = accel_nop,
>> +    .info = noaccel_info,
>>  };
>>
>> diff --git a/accel.h b/accel.h
>> index 935cfef..549ce01 100644
>> --- a/accel.h
>> +++ b/accel.h
>> @@ -1,11 +1,14 @@
>>  #ifndef _ACCEL_H_
>>  #define _ACCEL_H_
>>
>> +#define MAX_INFO_BUF 1024
>> +
>>  typedef struct QEMUAccel {
>>      void (*cpu_interrupt)(CPUState *env);
>>      void (*init_env)(CPUState *env);
>>      void (*flush_cache)(CPUState *env, int global);
>>      void (*flush_page)(CPUState *env, target_ulong addr);
>> +    int (*info)(CPUState *env, char *buf);
>>  } QEMUAccel;
>>
>>  extern QEMUAccel *current_accel;
>> @@ -35,4 +38,9 @@ static inline void accel_flush_page(CPUState *env, target_ulong addr)
>>  {
>>      current_accel->flush_page(env, addr);
>>  }
>> +
>> +static inline int accel_info(CPUState *env, char *buf)
>> +{
>> +    return current_accel->info(env, buf);
>> +}
>>  #endif
>> diff --git a/kqemu.c b/kqemu.c
>> index 3f2433a..424d8f4 100644
>> --- a/kqemu.c
>> +++ b/kqemu.c
>> @@ -1047,11 +1047,37 @@ static void qpi_init(void)
>>                                   0x1000, qpi_io_memory);
>>  }
>>
>> +static int kqemu_info(CPUState *env, char *buf)
>> +{
>> +    int val, len;
>> +    int bufsiz = MAX_INFO_BUF;
>>   
>
> Why not just pass bufsiz as an argument to kqemu_info?
ok, this makes sense.

thanks.
>
>> +    if (accel_info(env, buf))
>> +        term_printf(buf);
>>   
>
> You should do term_printf("%s", buf);  This is a common exploit if  
> there's ever a chance that buf has user-originated data.  Therefore,  
> it's good practice to always use ("%s", buf) instead of passing buf  
> directly.
>
> Regards,
>
> Anthony Liguori

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:17     ` Jan Kiszka
@ 2008-10-23 14:25       ` Anthony Liguori
  2008-10-23 15:08         ` Leonardo Reiter
  2008-10-24 15:37         ` [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
  0 siblings, 2 replies; 80+ messages in thread
From: Anthony Liguori @ 2008-10-23 14:25 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Glauber Costa, jes, qemu-devel, avi, dmitry.baryshkov

Jan Kiszka wrote:
> Anthony Liguori wrote:
>   
>> The idea behind this patch is that currently kqemu uses /dev/shm for
>> memory allocations instead of anonymous memory (like the rest of QEMU). 
>> Instead of introducing YA hook, we can just switch kqemu to use
>> anonymous memory and eliminate the special case.
>>
>> If I recall correctly, the reason for using /dev/shm was concern that
>> get_user_pages() didn't do the right thing for anonymous memory and the
>> use of /dev/shm was a hack around that.  However, I'm not sure that was
>> ever the case.  Certainly, with any sufficiently modern kernel
>> get_user_pages() does what one would expect.  KVM uses get_user_pages()
>> on anonymous memory in roughly the same way kqemu uses it now.
>>
>> So I think it's safe to make the switch.  Fabrice, what do you think?
>>     
>
> This hack-around, was it purely Linux-motivated? Or did/do other OSes
> have similar issues?
>   

/dev/shm doesn't exist on anything but Linux.

Regards,

Anthony Liguori

> Jan
>
>   

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 06/32] split kqemu_init into two
  2008-10-23 13:58   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:28     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:28 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

On Thu, Oct 23, 2008 at 08:58:48AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> From: Glauber Costa <gcosta@redhat.com>
>>
>> we separate kqemu_init() into a part that depends on env,
>> and other that does not. The later can be initialized earlier
>>   
>
> This patch seems harmless but I can't reasonably infer why this change  
> is necessary.  What's the advantage of splitting the initialization into  
> two parts?
>
the previous version receives a CPUState parameter. If we do that, we never 
give the accelerator the chance to care for its own CPUState. So that's the reason
behind the split: First, we kickstart the accelerator, which can suceed / fail.
Later on, we overwrite the cpu_env initialization to give the accel a chance.

> Regards,
>
> Anthony Liguori
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 24/32] check wether kqemu is enabled in open code
  2008-10-23 14:23   ` Anthony Liguori
@ 2008-10-23 14:31     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:31 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: jan.kiszka, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 09:23:18AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> kqemu is still too much spread around. The proper fix
>> usually involves rethinking a bit of kqemu logic so for now,
>> just check whether or not kqemu is enabled. If the kqemu accelerator
>> is not present, consider it not. Otherwise, check env field.
>>
>> Signed-off-by: Glauber Costa <glommer@redhat.com>
>> ---
>>  cpu-exec.c |    2 +-
>>  kqemu.c    |   21 +++++++++++++++++++++
>>  kqemu.h    |    3 +++
>>  3 files changed, 25 insertions(+), 1 deletions(-)
>>
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index 18908d5..b47cf43 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
>>                  {
>>                      if (next_tb != 0 &&
>>  #ifdef USE_KQEMU
>> -                        (env->kqemu_enabled != 2) &&
>> +                        (!kqemu_kernel_enabled(env)) &&
>>  #endif
>>                          tb->page_addr[1] == -1) {
>>                      tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
>> diff --git a/kqemu.c b/kqemu.c
>> index 16ebe7d..f99a4f1 100644
>> --- a/kqemu.c
>> +++ b/kqemu.c
>> @@ -126,6 +126,27 @@ static int is_cpuid_supported(void)
>>  }
>>  #endif
>>
>> +/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
>> + * altogether
>> + */
>> +int kqemu_is_enabled(CPUState *env)
>> +{
>> +    if (strcasecmp(current_accel->name, "kqemu")) {
>> +        return 0;
>> +    }
>> +
>> +    return env->kqemu_enabled;
>> +
>> +}
>> +
>> +int kqemu_kernel_enabled(CPUState *env)
>> +{
>> +    if (strcasecmp(current_accel->name, "kqemu")) {
>> +        return 0;
>> +    }
>> +    return env->kqemu_enabled == 2;
>> +}
>>   
>
> Why is kqemu_enabled part of the vcpu state?  Wouldn't it always be 0  
> even if we weren't using the accelerator?
It's temporary, to keep things compiling/working. It's dropped in a later patch.

>
> Regards,
>
> Anthony Liguori
>
>>  static void kqemu_update_cpuid(CPUState *env)
>>  {
>>      int critical_features_mask, features, ext_features, ext_features_mask;
>> diff --git a/kqemu.h b/kqemu.h
>> index cf14179..62ba1d9 100644
>> --- a/kqemu.h
>> +++ b/kqemu.h
>> @@ -157,6 +157,9 @@ struct kqemu_phys_mem {
>>  #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
>>  #endif
>>
>> +int kqemu_is_enabled(CPUState *env);
>> +int kqemu_kernel_enabled(CPUState *env);
>> +
>>  typedef struct KQEMUCPUstate {
>>      int kqemu_enabled;
>>      int last_io_time;
>>   
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 22/32] add next_cpu_index
  2008-10-23 14:21   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 14:37     ` Glauber Costa
  2008-10-23 14:40       ` Jan Kiszka
  0 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:37 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: jan.kiszka, jes, qemu-devel, avi, Glauber Costa, dmitry.baryshkov

On Thu, Oct 23, 2008 at 09:21:45AM -0500, Anthony Liguori wrote:
> Glauber Costa wrote:
>> From: Glauber Costa <gcosta@redhat.com>
>>
>> separate the logic for calculating the next cpu index
>> from cpu creation. It will allow others to query what's
>> the next cpu index to be created before cpu creation.
>>   
>
> What is this useful for?
In earlier versions of the series, I was passing the cpu_index to init_env.
So I guess it's just a die hard patch that survived the reworks. It can be dropped
now (although I believe its clearer this way).

>
> Regards,
>
> Anthony Liguori
>
>> Signed-off-by: Glauber Costa <gcosta@redhat.com>
>> ---
>>  exec.c |   22 ++++++++++++++--------
>>  1 files changed, 14 insertions(+), 8 deletions(-)
>>
>> diff --git a/exec.c b/exec.c
>> index 80b8a78..7fe7eeb 100644
>> --- a/exec.c
>> +++ b/exec.c
>> @@ -526,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
>>  }
>>  #endif
>>
>> -void cpu_exec_init(CPUState *env)
>> +int next_cpu_index(void)
>>  {
>>      CPUState **penv;
>> -    int cpu_index;
>> +    int cpu_index = 0;
>>
>> -    env->next_cpu = NULL;
>>      penv = &first_cpu;
>> -    cpu_index = 0;
>> +
>>      while (*penv != NULL) {
>>          penv = (CPUState **)&(*penv)->next_cpu;
>>          cpu_index++;
>>      }
>> -    env->cpu_index = cpu_index;
>> +    return cpu_index;
>> +}
>> +
>> +void cpu_exec_init(CPUState *env)
>> +{
>> +    env->next_cpu = NULL;
>> +    env->cpu_index = next_cpu_index();
>>      env->nb_watchpoints = 0;
>> -    *penv = env;
>> +    if (env->cpu_index == 0)
>> +        first_cpu = env;
>>  #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>> -    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
>> +    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
>>                      cpu_common_save, cpu_common_load, env);
>> -    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
>> +    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
>>                      cpu_save, cpu_load, env);
>>  #endif
>>  }
>>   
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 22/32] add next_cpu_index
  2008-10-23 14:37     ` Glauber Costa
@ 2008-10-23 14:40       ` Jan Kiszka
  2008-10-23 14:55         ` Glauber Costa
  0 siblings, 1 reply; 80+ messages in thread
From: Jan Kiszka @ 2008-10-23 14:40 UTC (permalink / raw)
  To: Glauber Costa
  Cc: Anthony Liguori, jes, qemu-devel, avi, Glauber Costa,
	dmitry.baryshkov

Glauber Costa wrote:
> On Thu, Oct 23, 2008 at 09:21:45AM -0500, Anthony Liguori wrote:
>> Glauber Costa wrote:
>>> From: Glauber Costa <gcosta@redhat.com>
>>>
>>> separate the logic for calculating the next cpu index
>>> from cpu creation. It will allow others to query what's
>>> the next cpu index to be created before cpu creation.
>>>   
>> What is this useful for?
> In earlier versions of the series, I was passing the cpu_index to init_env.
> So I guess it's just a die hard patch that survived the reworks. It can be dropped
> now (although I believe its clearer this way).

Why not keep track of the last assigned cpu_index in a global or static
variable? That should be clearer and avoids the iteration (which is
basically a count-how-many-cpus-we-already-have loop).

Jan

> 
>> Regards,
>>
>> Anthony Liguori
>>
>>> Signed-off-by: Glauber Costa <gcosta@redhat.com>
>>> ---
>>>  exec.c |   22 ++++++++++++++--------
>>>  1 files changed, 14 insertions(+), 8 deletions(-)
>>>
>>> diff --git a/exec.c b/exec.c
>>> index 80b8a78..7fe7eeb 100644
>>> --- a/exec.c
>>> +++ b/exec.c
>>> @@ -526,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
>>>  }
>>>  #endif
>>>
>>> -void cpu_exec_init(CPUState *env)
>>> +int next_cpu_index(void)
>>>  {
>>>      CPUState **penv;
>>> -    int cpu_index;
>>> +    int cpu_index = 0;
>>>
>>> -    env->next_cpu = NULL;
>>>      penv = &first_cpu;
>>> -    cpu_index = 0;
>>> +
>>>      while (*penv != NULL) {
>>>          penv = (CPUState **)&(*penv)->next_cpu;
>>>          cpu_index++;
>>>      }
>>> -    env->cpu_index = cpu_index;
>>> +    return cpu_index;
>>> +}
>>> +
>>> +void cpu_exec_init(CPUState *env)
>>> +{
>>> +    env->next_cpu = NULL;
>>> +    env->cpu_index = next_cpu_index();
>>>      env->nb_watchpoints = 0;
>>> -    *penv = env;
>>> +    if (env->cpu_index == 0)
>>> +        first_cpu = env;
>>>  #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
>>> -    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
>>> +    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
>>>                      cpu_common_save, cpu_common_load, env);
>>> -    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
>>> +    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
>>>                      cpu_save, cpu_load, env);
>>>  #endif
>>>  }
>>>   


-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 24/32] check wether kqemu is enabled in open code
  2008-10-23 13:38   ` [Qemu-devel] " Jan Kiszka
@ 2008-10-23 14:49     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:49 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: aliguori, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 03:38:45PM +0200, Jan Kiszka wrote:
> Glauber Costa wrote:
> > kqemu is still too much spread around. The proper fix
> > usually involves rethinking a bit of kqemu logic so for now,
> > just check whether or not kqemu is enabled. If the kqemu accelerator
> > is not present, consider it not. Otherwise, check env field.
> > 
> > Signed-off-by: Glauber Costa <glommer@redhat.com>
> > ---
> >  cpu-exec.c |    2 +-
> >  kqemu.c    |   21 +++++++++++++++++++++
> >  kqemu.h    |    3 +++
> >  3 files changed, 25 insertions(+), 1 deletions(-)
> > 
> > diff --git a/cpu-exec.c b/cpu-exec.c
> > index 18908d5..b47cf43 100644
> > --- a/cpu-exec.c
> > +++ b/cpu-exec.c
> > @@ -599,7 +599,7 @@ int cpu_exec(CPUState *env1)
> >                  {
> >                      if (next_tb != 0 &&
> >  #ifdef USE_KQEMU
> > -                        (env->kqemu_enabled != 2) &&
> > +                        (!kqemu_kernel_enabled(env)) &&
> >  #endif
> 
> If this ifdef is still here to foster rethinking of the check - OK :).
> Otherwise I would suggest to wrap kqemu_kernel_enabled for the
> !USE_KQEMU case.
Yes. Ideally, it should disappear, so I see no value of "solving" it.

> 
> >                          tb->page_addr[1] == -1) {
> >                      tb_add_jump((TranslationBlock *)(next_tb & ~3), next_tb & 3, tb);
> > diff --git a/kqemu.c b/kqemu.c
> > index 16ebe7d..f99a4f1 100644
> > --- a/kqemu.c
> > +++ b/kqemu.c
> > @@ -126,6 +126,27 @@ static int is_cpuid_supported(void)
> >  }
> >  #endif
> >  
> > +/* FIXME: Should not be needed, since ideally, QEMUAccel would avoid all kqemu tests
> > + * altogether
> > + */
> > +int kqemu_is_enabled(CPUState *env)
> > +{
> > +    if (strcasecmp(current_accel->name, "kqemu")) {
> > +        return 0;
> > +    }
> > +
> > +    return env->kqemu_enabled;
> > +
> > +}
> > +
> > +int kqemu_kernel_enabled(CPUState *env)
> > +{
> > +    if (strcasecmp(current_accel->name, "kqemu")) {
> > +        return 0;
> > +    }
> > +    return env->kqemu_enabled == 2;
> > +}
> > +
> >  static void kqemu_update_cpuid(CPUState *env)
> >  {
> >      int critical_features_mask, features, ext_features, ext_features_mask;
> > diff --git a/kqemu.h b/kqemu.h
> > index cf14179..62ba1d9 100644
> > --- a/kqemu.h
> > +++ b/kqemu.h
> > @@ -157,6 +157,9 @@ struct kqemu_phys_mem {
> >  #define KQEMU_SET_PHYS_MEM     _IOW('q', 5, struct kqemu_phys_mem)
> >  #endif
> >  
> > +int kqemu_is_enabled(CPUState *env);
> > +int kqemu_kernel_enabled(CPUState *env);
> > +
> >  typedef struct KQEMUCPUstate {
> >      int kqemu_enabled;
> >      int last_io_time;
> 
> Jan
> 
> -- 
> Siemens AG, Corporate Technology, CT SE 2
> Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 22/32] add next_cpu_index
  2008-10-23 14:40       ` Jan Kiszka
@ 2008-10-23 14:55         ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 14:55 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony Liguori, jes, qemu-devel, avi, Glauber Costa,
	dmitry.baryshkov

On Thu, Oct 23, 2008 at 04:40:49PM +0200, Jan Kiszka wrote:
> Glauber Costa wrote:
> > On Thu, Oct 23, 2008 at 09:21:45AM -0500, Anthony Liguori wrote:
> >> Glauber Costa wrote:
> >>> From: Glauber Costa <gcosta@redhat.com>
> >>>
> >>> separate the logic for calculating the next cpu index
> >>> from cpu creation. It will allow others to query what's
> >>> the next cpu index to be created before cpu creation.
> >>>   
> >> What is this useful for?
> > In earlier versions of the series, I was passing the cpu_index to init_env.
> > So I guess it's just a die hard patch that survived the reworks. It can be dropped
> > now (although I believe its clearer this way).
> 
> Why not keep track of the last assigned cpu_index in a global or static
> variable? That should be clearer and avoids the iteration (which is
> basically a count-how-many-cpus-we-already-have loop).
I like this. A "next_cpu_index()" function that increments it atomically would
do just fine. We don't have this kind of race yet for lack of smpbility, but it's
one less thing to fix in the future.

> 
> Jan
> 
> > 
> >> Regards,
> >>
> >> Anthony Liguori
> >>
> >>> Signed-off-by: Glauber Costa <gcosta@redhat.com>
> >>> ---
> >>>  exec.c |   22 ++++++++++++++--------
> >>>  1 files changed, 14 insertions(+), 8 deletions(-)
> >>>
> >>> diff --git a/exec.c b/exec.c
> >>> index 80b8a78..7fe7eeb 100644
> >>> --- a/exec.c
> >>> +++ b/exec.c
> >>> @@ -526,25 +526,31 @@ static int cpu_common_load(QEMUFile *f, void *opaque, int version_id)
> >>>  }
> >>>  #endif
> >>>
> >>> -void cpu_exec_init(CPUState *env)
> >>> +int next_cpu_index(void)
> >>>  {
> >>>      CPUState **penv;
> >>> -    int cpu_index;
> >>> +    int cpu_index = 0;
> >>>
> >>> -    env->next_cpu = NULL;
> >>>      penv = &first_cpu;
> >>> -    cpu_index = 0;
> >>> +
> >>>      while (*penv != NULL) {
> >>>          penv = (CPUState **)&(*penv)->next_cpu;
> >>>          cpu_index++;
> >>>      }
> >>> -    env->cpu_index = cpu_index;
> >>> +    return cpu_index;
> >>> +}
> >>> +
> >>> +void cpu_exec_init(CPUState *env)
> >>> +{
> >>> +    env->next_cpu = NULL;
> >>> +    env->cpu_index = next_cpu_index();
> >>>      env->nb_watchpoints = 0;
> >>> -    *penv = env;
> >>> +    if (env->cpu_index == 0)
> >>> +        first_cpu = env;
> >>>  #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)
> >>> -    register_savevm("cpu_common", cpu_index, CPU_COMMON_SAVE_VERSION,
> >>> +    register_savevm("cpu_common", env->cpu_index, CPU_COMMON_SAVE_VERSION,
> >>>                      cpu_common_save, cpu_common_load, env);
> >>> -    register_savevm("cpu", cpu_index, CPU_SAVE_VERSION,
> >>> +    register_savevm("cpu", env->cpu_index, CPU_SAVE_VERSION,
> >>>                      cpu_save, cpu_load, env);
> >>>  #endif
> >>>  }
> >>>   
> 
> 
> -- 
> Siemens AG, Corporate Technology, CT SE 2
> Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:25       ` Anthony Liguori
@ 2008-10-23 15:08         ` Leonardo Reiter
  2008-10-23 15:20           ` Leonardo Reiter
  2008-10-24 15:37         ` [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
  1 sibling, 1 reply; 80+ messages in thread
From: Leonardo Reiter @ 2008-10-23 15:08 UTC (permalink / raw)
  To: qemu-devel

On Thu, Oct 23, 2008 at 10:25 AM, Anthony Liguori <aliguori@us.ibm.com> wrote:
> Jan Kiszka wrote:
>>
>> This hack-around, was it purely Linux-motivated? Or did/do other OSes
>> have similar issues?
>>
>
> /dev/shm doesn't exist on anything but Linux.
>
> Regards,
>
> Anthony Liguori
>
>> Jan

This should be tested well on Solaris 10, especially with -m values
approaching 1GB and -kernel-kqemu.  The Solaris version would use /tmp
rather than /dev/shm, but iirc there were problems when using
MAP_ANONYMOUS.

Also, on Linux, does anyone know what minimum kernel version is needed
to not need the /dev/shm hack?

Thanks,

Leo Reiter

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 17/32] build list of available accelerators
  2008-10-23 13:45   ` [Qemu-devel] " Avi Kivity
@ 2008-10-23 15:09     ` Glauber Costa
  2008-10-23 15:15       ` Avi Kivity
  0 siblings, 1 reply; 80+ messages in thread
From: Glauber Costa @ 2008-10-23 15:09 UTC (permalink / raw)
  To: Avi Kivity
  Cc: aliguori, jan.kiszka, jes, qemu-devel, Glauber Costa,
	dmitry.baryshkov

On Thu, Oct 23, 2008 at 03:45:02PM +0200, Avi Kivity wrote:
> Glauber Costa wrote:
>> From: Glauber Costa <gcosta@redhat.com>
>>
>> instead of hardcoding kqemu_start() in exec.c, which would require
>> such a hack for all available accelerators, semantics of register_qemu_accel()
>> is changed a little bit. It only builds a list of available accelerators.
>> The last one registered is the first tried.
>>
>> This is a temporary solution, since we don't control exactly the order in which
>> things are loaded by the constructor attributes. The final goal is to have command
>> line switches and priority lists to determine that.
>>
>> "info accelerator" is changed to accomodate it. It now prints a list of available
>> accelerators, and only if one of them is active, a detailed description of it is printed.
>>
>>  #define MAX_INFO_BUF 1024
>>   typedef struct QEMUAccel {
>> +    char *name;
>>   
>
> const, or warnings you get.
>
>>  +typedef struct QEMUCont {
>> +    QEMUAccel *acc;
>> +    int active;
>> +    struct QEMUCont *next;
>> +} QEMUCont;
>>   
>
> The name is unclear.  But you could fold the structure into QEMUAccel, no?
Yes, it was folded in my first version. It is separated just to allow external
accelerators to register themselves without messing with the accelerator list, which
would be internal. But I'm probably just being overzealous.

>
> -- 
> I have a truly marvellous patch that fixes the bug which this
> signature is too narrow to contain.
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 17/32] build list of available accelerators
  2008-10-23 15:09     ` Glauber Costa
@ 2008-10-23 15:15       ` Avi Kivity
  0 siblings, 0 replies; 80+ messages in thread
From: Avi Kivity @ 2008-10-23 15:15 UTC (permalink / raw)
  To: Glauber Costa
  Cc: aliguori, jan.kiszka, jes, qemu-devel, Glauber Costa,
	dmitry.baryshkov


>>>  +typedef struct QEMUCont {
>>> +    QEMUAccel *acc;
>>> +    int active;
>>> +    struct QEMUCont *next;
>>> +} QEMUCont;
>>>   
>>>       
>> The name is unclear.  But you could fold the structure into QEMUAccel, no?
>>     
> Yes, it was folded in my first version. It is separated just to allow external
> accelerators to register themselves without messing with the accelerator list, which
> would be internal. But I'm probably just being overzealous.
>
>   

You could still have a registration function.  The accelerator itself 
would not need to touch the members.

-- 
I have a truly marvellous patch that fixes the bug which this
signature is too narrow to contain.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 15:08         ` Leonardo Reiter
@ 2008-10-23 15:20           ` Leonardo Reiter
  2008-10-24 19:30             ` Andreas Färber
  0 siblings, 1 reply; 80+ messages in thread
From: Leonardo Reiter @ 2008-10-23 15:20 UTC (permalink / raw)
  To: qemu-devel

On Thu, Oct 23, 2008 at 11:08 AM, Leonardo Reiter <lreiter76@gmail.com> wrote:
> This should be tested well on Solaris 10, especially with -m values
> approaching 1GB and -kernel-kqemu.  The Solaris version would use /tmp
> rather than /dev/shm, but iirc there were problems when using
> MAP_ANONYMOUS.
>
> Also, on Linux, does anyone know what minimum kernel version is needed
> to not need the /dev/shm hack?
>
Please disregard the Solaris bit as the 1.4.0 version of KQEMU is not
widely available there yet, so you can't use the SVN version of QEMU
with KQEMU anyway AFAIK.  I'd be glad to look at this in the (somewhat
distant) future and come up with a patch if anonymous memory on
Solaris is not stable.

But the Linux bit is still good to understand.  I know Fabrice put
this limitation in specifically because of problems with Linux
kernels, so it would be good to know what minimum kernel version seems
to have this fixed.

Thanks,

Leo Reiter

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 20/32] accel_trace_io
  2008-10-23 14:20   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-23 17:26     ` Glauber de Oliveira Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber de Oliveira Costa @ 2008-10-23 17:26 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: jan kiszka, Glauber Costa, jes, qemu-devel, avi, dmitry baryshkov


----- "Anthony Liguori" <aliguori@us.ibm.com> wrote:

> Glauber Costa wrote:
> > From: Glauber Costa <gcosta@redhat.com>
> >
> > kqemu keeps trace of the last io done. Do it through
> > an accel_wrapper.
> >   
> 
> The hooks here are probably not the best they could be.  The purpose
> of 
> this code in kqemu, from what I can tell, is to control how long we
> run 
> in softmmu before trying to run in the kernel again.  I presume this
> is 
> mainly for kernel-kqemu.
> 
> When kernel-kqemu encounters an instruction it can't handle, it drops
> to 
> userspace and runs in softmmu for a while.  The question is how long 
> should it run in softmmu and this is a heuristic.  This is what the
> code 
> is doing.
> 
> Regards,

My proposal is:

* add a hook for in and another for out operations. It's generic enough to be useful
  for other purposes in the future. KVM does not need to do anything in here, and kqemu can
  just record the last io time
* add a hook at th end of cpu_exec, that allows the accel to shut off current execution based
  on any criteria it wants to. accel_break_loop (the current one) seems a fine name for it.
  To be even more explicit, the accel can just return 1 or 0 indicating whether or not the current
  execution loop should be stopped, and cpu_loop_exit() is called based on the return value.

What do you think?

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 14:25       ` Anthony Liguori
  2008-10-23 15:08         ` Leonardo Reiter
@ 2008-10-24 15:37         ` Glauber Costa
  1 sibling, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-24 15:37 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Jan Kiszka, jes, qemu-devel, avi, dmitry.baryshkov

On Thu, Oct 23, 2008 at 09:25:12AM -0500, Anthony Liguori wrote:
> Jan Kiszka wrote:
>> Anthony Liguori wrote:
>>   
>>> The idea behind this patch is that currently kqemu uses /dev/shm for
>>> memory allocations instead of anonymous memory (like the rest of 
>>> QEMU). Instead of introducing YA hook, we can just switch kqemu to 
>>> use
>>> anonymous memory and eliminate the special case.
>>>
>>> If I recall correctly, the reason for using /dev/shm was concern that
>>> get_user_pages() didn't do the right thing for anonymous memory and the
>>> use of /dev/shm was a hack around that.  However, I'm not sure that was
>>> ever the case.  Certainly, with any sufficiently modern kernel
>>> get_user_pages() does what one would expect.  KVM uses get_user_pages()
>>> on anonymous memory in roughly the same way kqemu uses it now.
>>>
>>> So I think it's safe to make the switch.  Fabrice, what do you think?
>>>     
>>
>> This hack-around, was it purely Linux-motivated? Or did/do other OSes
>> have similar issues?
>>   
>
> /dev/shm doesn't exist on anything but Linux.
>
> Regards,
I'm dropping this from the accel series until we reach a conclusion.
This is not exactly needed for the health of the series, just for kqemu
decoupling. This can proceed in parallel.

>
> Anthony Liguori
>
>> Jan
>>
>>   
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-23 15:20           ` Leonardo Reiter
@ 2008-10-24 19:30             ` Andreas Färber
  2008-10-24 19:59               ` Ben Taylor
  0 siblings, 1 reply; 80+ messages in thread
From: Andreas Färber @ 2008-10-24 19:30 UTC (permalink / raw)
  To: qemu-devel


Am 23.10.2008 um 17:20 schrieb Leonardo Reiter:

> On Thu, Oct 23, 2008 at 11:08 AM, Leonardo Reiter  
> <lreiter76@gmail.com> wrote:
>> This should be tested well on Solaris 10, especially with -m values
>> approaching 1GB and -kernel-kqemu.  The Solaris version would use / 
>> tmp
>> rather than /dev/shm, but iirc there were problems when using
>> MAP_ANONYMOUS.
>>
>> Also, on Linux, does anyone know what minimum kernel version is  
>> needed
>> to not need the /dev/shm hack?
>>
> Please disregard the Solaris bit as the 1.4.0 version of KQEMU is not
> widely available there yet, so you can't use the SVN version of QEMU
> with KQEMU anyway AFAIK.  I'd be glad to look at this in the (somewhat
> distant) future and come up with a patch if anonymous memory on
> Solaris is not stable.

OpenSolaris.org has a kqemu version that I've been happily using there  
with SVN. It supposedly supports Solaris 9 and 8, so by inference 10  
as well, I'd hope.
http://www.opensolaris.org/os/project/qemu/downloads/

Last time I heard it wasn't merged upstream, so it would be good to  
check how well the Solaris (and FreeBSD?) kqemu variants work with  
this series. Maybe merge into the current codebase before making too  
much assumptions for the new accel interface?

Andreas

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu.
  2008-10-24 19:30             ` Andreas Färber
@ 2008-10-24 19:59               ` Ben Taylor
  2008-10-25 10:17                 ` [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.) Andreas Färber
  0 siblings, 1 reply; 80+ messages in thread
From: Ben Taylor @ 2008-10-24 19:59 UTC (permalink / raw)
  To: Andreas Färber; +Cc: qemu-devel

On Fri, Oct 24, 2008 at 3:30 PM, Andreas Färber <andreas.faerber@web.de> wrote:
>
> Am 23.10.2008 um 17:20 schrieb Leonardo Reiter:
>
>> On Thu, Oct 23, 2008 at 11:08 AM, Leonardo Reiter <lreiter76@gmail.com>
>> wrote:
>>>
>>> This should be tested well on Solaris 10, especially with -m values
>>> approaching 1GB and -kernel-kqemu.  The Solaris version would use /tmp
>>> rather than /dev/shm, but iirc there were problems when using
>>> MAP_ANONYMOUS.
>>>
>>> Also, on Linux, does anyone know what minimum kernel version is needed
>>> to not need the /dev/shm hack?
>>>
>> Please disregard the Solaris bit as the 1.4.0 version of KQEMU is not
>> widely available there yet, so you can't use the SVN version of QEMU
>> with KQEMU anyway AFAIK.  I'd be glad to look at this in the (somewhat
>> distant) future and come up with a patch if anonymous memory on
>> Solaris is not stable.
>
> OpenSolaris.org has a kqemu version that I've been happily using there with
> SVN. It supposedly supports Solaris 9 and 8, so by inference 10 as well, I'd
> hope.
> http://www.opensolaris.org/os/project/qemu/downloads/

There are currently two versions.  1.3.0pre11 works with Solaris 9, 10 and
SXCE.  8 should work, but there are differences in the calls used in kqemu
depending on which kernel version of Solaris you're running.  that will work
with any svn up to the introduction of the 1.4.0 kqemu module.

I also ported 1.4.0pre1, and Juergen Keil and a Sun engineer found a couple
of bugs that should be squashed now.

However, the big problem I see is that the addition of c99 features
borks a qemu compile on Solaris, specfically around stdbool.h.
Turning on -std=c99 or -std=gnuc99 creates more problems because
gcc-3.4.3 provided by solaris doesn't accept the anonymous unions
that are prevalent around the new code, specifically nbd and vnc.

> Last time I heard it wasn't merged upstream, so it would be good to check
> how well the Solaris (and FreeBSD?) kqemu variants work with this series.
> Maybe merge into the current codebase before making too much assumptions for
> the new accel interface?
>

I'll give it a whirl.

Ben

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.)
  2008-10-24 19:59               ` Ben Taylor
@ 2008-10-25 10:17                 ` Andreas Färber
  2008-10-25 10:27                   ` Andreas Färber
  0 siblings, 1 reply; 80+ messages in thread
From: Andreas Färber @ 2008-10-25 10:17 UTC (permalink / raw)
  To: qemu-devel


Am 24.10.2008 um 21:59 schrieb Ben Taylor:

> the big problem I see is that the addition of c99 features
> borks a qemu compile on Solaris, specfically around stdbool.h.
> Turning on -std=c99 or -std=gnuc99 creates more problems because
> gcc-3.4.3 provided by solaris doesn't accept the anonymous unions
> that are prevalent around the new code, specifically nbd and vnc.

I just gave it a try on S10 5/08 amd64, using the gcc 3.4.3 from Sun  
and --disable-gcc-check

* configure complains about an illegal -q for grep.
It's used in a check for GNU ld. Could we use other options there or  
let grep be overridable to ggrep?

Since I am building on amd64, it also complained that libSDL is not  
amd64, so I use: --disable-sdl --disable-gfx-check

I can confirm the build failure due to stdbool.h. I therefore add: -- 
extra-cflags=-std=gnu99

sparc-softmmu then compiles fine.

For i386-softmmu however,

* I get a flood of warnings from softfloat_native.h due to  
redefinitions of isunordered etc. (defined in Sun's math_c99.h), and

* the build of `qemu` fails to link due to undefined symbols  
__builtin_isinf and __builtin_isnan in libqemu.a(op_helper.o).

Looking at fpu/softfloat_native.h I see it makes assumptions about  
these macros that turn wrong when using the C99 headers. Any  
suggestion what to do here? It does not seem to depend on the GCC  
version since I am encountering this on 3.4.3, not 4.x.

If I prepend "0 && " to the #if line to avoid the redefinitions, I get  
compilation errors about __builtin_* functions:

gmake[1]: Entering directory `/export/home/andreas/QEMU/qemu/i386- 
softmmu'
Makefile:701: no file name for `-include'
gcc -I. -I.. -I/export/home/andreas/QEMU/qemu/target-i386 -I/export/ 
home/andreas/QEMU/qemu -MMD -MT vl.o -MP -DNEED_CPU_H -D_GNU_SOURCE - 
D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I/export/home/andreas/QEMU/ 
qemu/tcg -I/export/home/andreas/QEMU/qemu/tcg/x86_64 -I/export/home/ 
andreas/QEMU/qemu/fpu -DHAS_AUDIO -DHAS_AUDIO_CHOICE -I/export/home/ 
andreas/QEMU/qemu/slirp -std=gnu99 -O2 -g -fno-strict-aliasing -Wall - 
Wundef -Wendif-labels -Wwrite-strings  -m64 -c -o vl.o /export/home/ 
andreas/QEMU/qemu/vl.c
In file included from /export/home/andreas/QEMU/qemu/fpu/softfloat.h: 
440,
                  from /export/home/andreas/QEMU/qemu/target-i386/ 
cpu.h:47,
                  from ../qemu-common.h:62,
                  from /export/home/andreas/QEMU/qemu/hw/hw.h:5,
                  from /export/home/andreas/QEMU/qemu/vl.c:24:
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float32_le_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:217: error:  
syntax error before "__builtin_islessequal"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:218: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float32_lt_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:221: error:  
syntax error before "__builtin_isless"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:222: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float32_unordered':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:225: error:  
syntax error before "__builtin_isunordered"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:227: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float64_le_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:307: error:  
syntax error before "__builtin_islessequal"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:308: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float64_lt_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:311: error:  
syntax error before "__builtin_isless"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:313: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`float64_unordered':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:316: error:  
syntax error before "__builtin_isunordered"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:318: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`floatx80_le_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:394: error:  
syntax error before "__builtin_islessequal"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:395: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`floatx80_lt_quiet':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:398: error:  
syntax error before "__builtin_isless"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:400: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
`floatx80_unordered':
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:403: error:  
syntax error before "__builtin_isunordered"
/export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:405: warning: no  
return statement in function returning non-void
/export/home/andreas/QEMU/qemu/vl.c: At top level:
/export/home/andreas/QEMU/qemu/vl.c:205: warning: 'no_frame' defined  
but not used
/export/home/andreas/QEMU/qemu/vl.c:5372: warning: 'qemu_find_bt_vlan'  
defined but not used
gmake[1]: *** [vl.o] Error 1
gmake[1]: Leaving directory `/export/home/andreas/QEMU/qemu/i386- 
softmmu'
gmake: *** [subdir-i386-softmmu] Error 2

softfloat-native.h:217 does a simple "return islessequal(a, b);" -  
Sun's header has it defined as ((x) __builtin_islessequal(y)). This  
looks a little strange to me...
Should we continue to override their macros, using #undef to avoid all  
the warnings, and define some additional ones for isinf and isnan, or  
is there a better solution?

The -include warning above appears to be related to dependency  
tracking only.

Andreas

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.)
  2008-10-25 10:17                 ` [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.) Andreas Färber
@ 2008-10-25 10:27                   ` Andreas Färber
  2008-10-25 10:45                     ` Blue Swirl
  0 siblings, 1 reply; 80+ messages in thread
From: Andreas Färber @ 2008-10-25 10:27 UTC (permalink / raw)
  To: qemu-devel


Am 25.10.2008 um 12:17 schrieb Andreas Färber:

>
> Am 24.10.2008 um 21:59 schrieb Ben Taylor:
>
>> the big problem I see is that the addition of c99 features
>> borks a qemu compile on Solaris, specfically around stdbool.h.
>> Turning on -std=c99 or -std=gnuc99 creates more problems because
>> gcc-3.4.3 provided by solaris doesn't accept the anonymous unions
>> that are prevalent around the new code, specifically nbd and vnc.
>
> I just gave it a try on S10 5/08 amd64, using the gcc 3.4.3 from Sun  
> and --disable-gcc-check
>
> * configure complains about an illegal -q for grep.
> It's used in a check for GNU ld. Could we use other options there or  
> let grep be overridable to ggrep?
>
> Since I am building on amd64, it also complained that libSDL is not  
> amd64, so I use: --disable-sdl --disable-gfx-check
>
> I can confirm the build failure due to stdbool.h. I therefore add: -- 
> extra-cflags=-std=gnu99
>
> sparc-softmmu then compiles fine.

Small addition here: in hw/bt-hci.c in bt_submit_hci I spotted an  
implicit declaration of function `strndup'

This is at r5528 btw.

> For i386-softmmu however,
>
> * I get a flood of warnings from softfloat_native.h due to  
> redefinitions of isunordered etc. (defined in Sun's math_c99.h), and
>
> * the build of `qemu` fails to link due to undefined symbols  
> __builtin_isinf and __builtin_isnan in libqemu.a(op_helper.o).
>
> Looking at fpu/softfloat_native.h I see it makes assumptions about  
> these macros that turn wrong when using the C99 headers. Any  
> suggestion what to do here? It does not seem to depend on the GCC  
> version since I am encountering this on 3.4.3, not 4.x.
>
> If I prepend "0 && " to the #if line to avoid the redefinitions, I  
> get compilation errors about __builtin_* functions:
>
> gmake[1]: Entering directory `/export/home/andreas/QEMU/qemu/i386- 
> softmmu'
> Makefile:701: no file name for `-include'
> gcc -I. -I.. -I/export/home/andreas/QEMU/qemu/target-i386 -I/export/ 
> home/andreas/QEMU/qemu -MMD -MT vl.o -MP -DNEED_CPU_H -D_GNU_SOURCE - 
> D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I/export/home/andreas/ 
> QEMU/qemu/tcg -I/export/home/andreas/QEMU/qemu/tcg/x86_64 -I/export/ 
> home/andreas/QEMU/qemu/fpu -DHAS_AUDIO -DHAS_AUDIO_CHOICE -I/export/ 
> home/andreas/QEMU/qemu/slirp -std=gnu99 -O2 -g -fno-strict-aliasing - 
> Wall -Wundef -Wendif-labels -Wwrite-strings  -m64 -c -o vl.o /export/ 
> home/andreas/QEMU/qemu/vl.c
> In file included from /export/home/andreas/QEMU/qemu/fpu/softfloat.h: 
> 440,
>                 from /export/home/andreas/QEMU/qemu/target-i386/ 
> cpu.h:47,
>                 from ../qemu-common.h:62,
>                 from /export/home/andreas/QEMU/qemu/hw/hw.h:5,
>                 from /export/home/andreas/QEMU/qemu/vl.c:24:
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float32_le_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:217: error:  
> syntax error before "__builtin_islessequal"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:218: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float32_lt_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:221: error:  
> syntax error before "__builtin_isless"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:222: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float32_unordered':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:225: error:  
> syntax error before "__builtin_isunordered"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:227: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float64_le_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:307: error:  
> syntax error before "__builtin_islessequal"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:308: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float64_lt_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:311: error:  
> syntax error before "__builtin_isless"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:313: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `float64_unordered':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:316: error:  
> syntax error before "__builtin_isunordered"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:318: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `floatx80_le_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:394: error:  
> syntax error before "__builtin_islessequal"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:395: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `floatx80_lt_quiet':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:398: error:  
> syntax error before "__builtin_isless"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:400: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h: In function  
> `floatx80_unordered':
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:403: error:  
> syntax error before "__builtin_isunordered"
> /export/home/andreas/QEMU/qemu/fpu/softfloat-native.h:405: warning:  
> no return statement in function returning non-void
> /export/home/andreas/QEMU/qemu/vl.c: At top level:
> /export/home/andreas/QEMU/qemu/vl.c:205: warning: 'no_frame' defined  
> but not used
> /export/home/andreas/QEMU/qemu/vl.c:5372: warning:  
> 'qemu_find_bt_vlan' defined but not used
> gmake[1]: *** [vl.o] Error 1
> gmake[1]: Leaving directory `/export/home/andreas/QEMU/qemu/i386- 
> softmmu'
> gmake: *** [subdir-i386-softmmu] Error 2
>
> softfloat-native.h:217 does a simple "return islessequal(a, b);" -  
> Sun's header has it defined as ((x) __builtin_islessequal(y)). This  
> looks a little strange to me...
> Should we continue to override their macros, using #undef to avoid  
> all the warnings, and define some additional ones for isinf and  
> isnan, or is there a better solution?
>
> The -include warning above appears to be related to dependency  
> tracking only.
>
> Andreas
>
>
>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.)
  2008-10-25 10:27                   ` Andreas Färber
@ 2008-10-25 10:45                     ` Blue Swirl
  0 siblings, 0 replies; 80+ messages in thread
From: Blue Swirl @ 2008-10-25 10:45 UTC (permalink / raw)
  To: qemu-devel

On 10/25/08, Andreas Färber <andreas.faerber@web.de> wrote:
>
>  Am 25.10.2008 um 12:17 schrieb Andreas Färber:
>
>
> >
> > Am 24.10.2008 um 21:59 schrieb Ben Taylor:
> >
> >
> > > the big problem I see is that the addition of c99 features
> > > borks a qemu compile on Solaris, specfically around stdbool.h.
> > > Turning on -std=c99 or -std=gnuc99 creates more problems because
> > > gcc-3.4.3 provided by solaris doesn't accept the anonymous unions
> > > that are prevalent around the new code, specifically nbd and vnc.
> > >
> >
> > I just gave it a try on S10 5/08 amd64, using the gcc 3.4.3 from Sun and
> --disable-gcc-check
> >
> > * configure complains about an illegal -q for grep.
> > It's used in a check for GNU ld. Could we use other options there or let
> grep be overridable to ggrep?
> >
> > Since I am building on amd64, it also complained that libSDL is not amd64,
> so I use: --disable-sdl --disable-gfx-check
> >
> > I can confirm the build failure due to stdbool.h. I therefore add:
> --extra-cflags=-std=gnu99
> >
> > sparc-softmmu then compiles fine.
> >
>
>  Small addition here: in hw/bt-hci.c in bt_submit_hci I spotted an implicit
> declaration of function `strndup'

I get the same warning on OpenBSD, and there is also
/src/qemu/hw/bt-hci.c:1818: warning: assignment makes pointer from
integer without a cast

Maybe there should be a pstrdup function in cutils.c.

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH 20/32] accel_trace_io
  2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
  2008-10-23 14:20   ` [Qemu-devel] " Anthony Liguori
@ 2008-10-25 11:10   ` andrzej zaborowski
  2008-10-25 11:14     ` Glauber Costa
  1 sibling, 1 reply; 80+ messages in thread
From: andrzej zaborowski @ 2008-10-25 11:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

2008/10/23 Glauber Costa <glommer@redhat.com>:
> From: Glauber Costa <gcosta@redhat.com>
>
> kqemu keeps trace of the last io done. Do it through
> an accel_wrapper.
>
> Signed-off-by: Glauber Costa <gcosta@redhat.com>
> ---
>  accel.c            |    2 ++
>  accel.h            |   13 ++++++++++++-
>  cpu-exec.c         |    9 ++-------
>  kqemu.c            |   18 ++++++++++++++++++
>  softmmu_template.h |   10 ++++------
>  vl.c               |   30 ++++++------------------------
>  6 files changed, 44 insertions(+), 38 deletions(-)
>
> diff --git a/accel.c b/accel.c
> index bf1194d..0890039 100644
> --- a/accel.c
> +++ b/accel.c
> @@ -32,5 +32,7 @@ QEMUAccel noaccel = {
>     .get_real_ticks = cpu_get_ticks,
>  #endif
>     .register_physical_memory = accel_nop,
> +    .trace_io = accel_nop,
> +    .break_loop = accel_nop,
>  };
>
> diff --git a/accel.h b/accel.h
> index dbb6372..b37175b 100644
> --- a/accel.h
> +++ b/accel.h
> @@ -19,7 +19,8 @@ typedef struct QEMUAccel {
>  #endif
>     void (*register_physical_memory)(uint64_t start_addr,
>                                      ram_addr_t size, ram_addr_t phys_offset);
> -
> +    void (*trace_io)(CPUState *env);
> +    int (*break_loop)(CPUState *env);
>  } QEMUAccel;
>
>  typedef struct QEMUCont {
> @@ -142,4 +143,14 @@ static inline void accel_register_phys_mem(uint64_t start_addr,
>  {
>     current_accel->register_physical_memory(start_addr, size, phys_offset);
>  }
> +
> +static inline void accel_trace_io(CPUState *env)
> +{
> +    current_accel->trace_io(env);
> +}
> +
> +static inline int accel_break_loop(CPUState *env)
> +{
> +    return current_accel->break_loop(env);
> +}
>  #endif
> diff --git a/cpu-exec.c b/cpu-exec.c
> index 88b7d6f..18908d5 100644
> --- a/cpu-exec.c
> +++ b/cpu-exec.c
> @@ -36,6 +36,7 @@
>  #include <signal.h>
>  #include <sys/ucontext.h>
>  #endif
> +#include "accel.h"
>
>  #if defined(__sparc__) && !defined(HOST_SOLARIS)
>  // Work around ugly bugs in glibc that mangle global register contents
> @@ -646,13 +647,7 @@ int cpu_exec(CPUState *env1)
>                 }
>                 /* reset soft MMU for next block (it can currently
>                    only be set by a memory fault) */
> -#if defined(USE_KQEMU)
> -#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
> -                if (kqemu_is_ok(env) &&
> -                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
> -                    cpu_loop_exit();
> -                }
> -#endif
> +                accel_break_loop(env);
>             } /* for(;;) */
>         } else {
>             env_to_regs();
> diff --git a/kqemu.c b/kqemu.c
> index f4d905a..d38d0e3 100644
> --- a/kqemu.c
> +++ b/kqemu.c
> @@ -1107,6 +1107,22 @@ static int kqemu_profile(CPUState *env, char *buf)
>     return len;
>  }
>
> +static void kqemu_trace_io(CPUState *env)
> +{
> +    if (env)
> +        env->last_io_time = cpu_get_time_fast();
> +}
> +
> +static int kqemu_break_loop(CPUState *env)
> +{
> +#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
> +    if (kqemu_is_ok(env) &&
> +        (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
> +        return 1;
> +    }
> +    return 0;
> +}
> +
>  QEMUAccel kqemu_accel = {
>     .name = "KQEMU",
>     .cpu_interrupt = kqemu_cpu_interrupt,
> @@ -1125,6 +1141,8 @@ QEMUAccel kqemu_accel = {
>     .get_real_ticks = cpu_get_real_ticks,
>  #endif
>     .register_physical_memory = kqemu_set_phys_mem,
> +    .trace_io = kqemu_trace_io,
> +    .break_loop = kqemu_break_loop,
>  };
>
>  #endif
> diff --git a/softmmu_template.h b/softmmu_template.h
> index 98dd378..4945352 100644
> --- a/softmmu_template.h
> +++ b/softmmu_template.h
> @@ -47,6 +47,8 @@
>  #define ADDR_READ addr_read
>  #endif
>
> +#include "accel.h"
> +
>  static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
>                                                         int mmu_idx,
>                                                         void *retaddr);
> @@ -75,9 +77,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
>     res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
>  #endif
>  #endif /* SHIFT > 2 */
> -#ifdef USE_KQEMU
> -    env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>     return res;
>  }
>
> @@ -220,9 +220,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
>     io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
>  #endif
>  #endif /* SHIFT > 2 */
> -#ifdef USE_KQEMU
> -    env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>  }
>
>  void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
> diff --git a/vl.c b/vl.c
> index 964205d..e64becb 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -420,10 +420,7 @@ void cpu_outb(CPUState *env, int addr, int val)
>         fprintf(logfile, "outb: %04x %02x\n", addr, val);
>  #endif
>     ioport_write(0, addr, val);
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>  }
>
>  void cpu_outw(CPUState *env, int addr, int val)
> @@ -433,10 +430,7 @@ void cpu_outw(CPUState *env, int addr, int val)
>         fprintf(logfile, "outw: %04x %04x\n", addr, val);
>  #endif
>     ioport_write(1, addr, val);
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>  }
>
>  void cpu_outl(CPUState *env, int addr, int val)
> @@ -446,10 +440,7 @@ void cpu_outl(CPUState *env, int addr, int val)
>         fprintf(logfile, "outl: %04x %08x\n", addr, val);
>  #endif
>     ioport_write(2, addr, val);
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>  }
>
>  int cpu_inb(CPUState *env, int addr)
> @@ -460,10 +451,7 @@ int cpu_inb(CPUState *env, int addr)
>     if (loglevel & CPU_LOG_IOPORT)
>         fprintf(logfile, "inb : %04x %02x\n", addr, val);
>  #endif
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>     return val;
>  }
>
> @@ -475,10 +463,7 @@ int cpu_inw(CPUState *env, int addr)
>     if (loglevel & CPU_LOG_IOPORT)
>         fprintf(logfile, "inw : %04x %04x\n", addr, val);
>  #endif
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);
>     return val;
>  }
>
> @@ -490,10 +475,7 @@ int cpu_inl(CPUState *env, int addr)
>     if (loglevel & CPU_LOG_IOPORT)
>         fprintf(logfile, "inl : %04x %08x\n", addr, val);
>  #endif
> -#ifdef USE_KQEMU
> -    if (env)
> -        env->last_io_time = cpu_get_time_fast();
> -#endif
> +    accel_trace_io(env);

It would be great if all the new checks on the critical paths could
remain wrapped in some kind of #ifdef for archs that don't have any
acceleration implemented (also in other patches in this series).

[skipped a rant about the explosion of correctness fixes and clean-up
and some guests in practice booting nearly 2x slower compared to a
last year's qemu snapshot]

Regards

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [Qemu-devel] [PATCH 20/32] accel_trace_io
  2008-10-25 11:10   ` [Qemu-devel] " andrzej zaborowski
@ 2008-10-25 11:14     ` Glauber Costa
  0 siblings, 0 replies; 80+ messages in thread
From: Glauber Costa @ 2008-10-25 11:14 UTC (permalink / raw)
  To: qemu-devel
  Cc: aliguori, jan.kiszka, jes, avi, Glauber Costa, dmitry.baryshkov

On Sat, Oct 25, 2008 at 9:10 AM, andrzej zaborowski <balrogg@gmail.com> wrote:
> 2008/10/23 Glauber Costa <glommer@redhat.com>:
>> From: Glauber Costa <gcosta@redhat.com>
>>
>> kqemu keeps trace of the last io done. Do it through
>> an accel_wrapper.
>>
>> Signed-off-by: Glauber Costa <gcosta@redhat.com>
>> ---
>>  accel.c            |    2 ++
>>  accel.h            |   13 ++++++++++++-
>>  cpu-exec.c         |    9 ++-------
>>  kqemu.c            |   18 ++++++++++++++++++
>>  softmmu_template.h |   10 ++++------
>>  vl.c               |   30 ++++++------------------------
>>  6 files changed, 44 insertions(+), 38 deletions(-)
>>
>> diff --git a/accel.c b/accel.c
>> index bf1194d..0890039 100644
>> --- a/accel.c
>> +++ b/accel.c
>> @@ -32,5 +32,7 @@ QEMUAccel noaccel = {
>>     .get_real_ticks = cpu_get_ticks,
>>  #endif
>>     .register_physical_memory = accel_nop,
>> +    .trace_io = accel_nop,
>> +    .break_loop = accel_nop,
>>  };
>>
>> diff --git a/accel.h b/accel.h
>> index dbb6372..b37175b 100644
>> --- a/accel.h
>> +++ b/accel.h
>> @@ -19,7 +19,8 @@ typedef struct QEMUAccel {
>>  #endif
>>     void (*register_physical_memory)(uint64_t start_addr,
>>                                      ram_addr_t size, ram_addr_t phys_offset);
>> -
>> +    void (*trace_io)(CPUState *env);
>> +    int (*break_loop)(CPUState *env);
>>  } QEMUAccel;
>>
>>  typedef struct QEMUCont {
>> @@ -142,4 +143,14 @@ static inline void accel_register_phys_mem(uint64_t start_addr,
>>  {
>>     current_accel->register_physical_memory(start_addr, size, phys_offset);
>>  }
>> +
>> +static inline void accel_trace_io(CPUState *env)
>> +{
>> +    current_accel->trace_io(env);
>> +}
>> +
>> +static inline int accel_break_loop(CPUState *env)
>> +{
>> +    return current_accel->break_loop(env);
>> +}
>>  #endif
>> diff --git a/cpu-exec.c b/cpu-exec.c
>> index 88b7d6f..18908d5 100644
>> --- a/cpu-exec.c
>> +++ b/cpu-exec.c
>> @@ -36,6 +36,7 @@
>>  #include <signal.h>
>>  #include <sys/ucontext.h>
>>  #endif
>> +#include "accel.h"
>>
>>  #if defined(__sparc__) && !defined(HOST_SOLARIS)
>>  // Work around ugly bugs in glibc that mangle global register contents
>> @@ -646,13 +647,7 @@ int cpu_exec(CPUState *env1)
>>                 }
>>                 /* reset soft MMU for next block (it can currently
>>                    only be set by a memory fault) */
>> -#if defined(USE_KQEMU)
>> -#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
>> -                if (kqemu_is_ok(env) &&
>> -                    (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
>> -                    cpu_loop_exit();
>> -                }
>> -#endif
>> +                accel_break_loop(env);
>>             } /* for(;;) */
>>         } else {
>>             env_to_regs();
>> diff --git a/kqemu.c b/kqemu.c
>> index f4d905a..d38d0e3 100644
>> --- a/kqemu.c
>> +++ b/kqemu.c
>> @@ -1107,6 +1107,22 @@ static int kqemu_profile(CPUState *env, char *buf)
>>     return len;
>>  }
>>
>> +static void kqemu_trace_io(CPUState *env)
>> +{
>> +    if (env)
>> +        env->last_io_time = cpu_get_time_fast();
>> +}
>> +
>> +static int kqemu_break_loop(CPUState *env)
>> +{
>> +#define MIN_CYCLE_BEFORE_SWITCH (100 * 1000)
>> +    if (kqemu_is_ok(env) &&
>> +        (cpu_get_time_fast() - env->last_io_time) >= MIN_CYCLE_BEFORE_SWITCH) {
>> +        return 1;
>> +    }
>> +    return 0;
>> +}
>> +
>>  QEMUAccel kqemu_accel = {
>>     .name = "KQEMU",
>>     .cpu_interrupt = kqemu_cpu_interrupt,
>> @@ -1125,6 +1141,8 @@ QEMUAccel kqemu_accel = {
>>     .get_real_ticks = cpu_get_real_ticks,
>>  #endif
>>     .register_physical_memory = kqemu_set_phys_mem,
>> +    .trace_io = kqemu_trace_io,
>> +    .break_loop = kqemu_break_loop,
>>  };
>>
>>  #endif
>> diff --git a/softmmu_template.h b/softmmu_template.h
>> index 98dd378..4945352 100644
>> --- a/softmmu_template.h
>> +++ b/softmmu_template.h
>> @@ -47,6 +47,8 @@
>>  #define ADDR_READ addr_read
>>  #endif
>>
>> +#include "accel.h"
>> +
>>  static DATA_TYPE glue(glue(slow_ld, SUFFIX), MMUSUFFIX)(target_ulong addr,
>>                                                         int mmu_idx,
>>                                                         void *retaddr);
>> @@ -75,9 +77,7 @@ static inline DATA_TYPE glue(io_read, SUFFIX)(target_phys_addr_t physaddr,
>>     res |= (uint64_t)io_mem_read[index][2](io_mem_opaque[index], physaddr + 4) << 32;
>>  #endif
>>  #endif /* SHIFT > 2 */
>> -#ifdef USE_KQEMU
>> -    env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>     return res;
>>  }
>>
>> @@ -220,9 +220,7 @@ static inline void glue(io_write, SUFFIX)(target_phys_addr_t physaddr,
>>     io_mem_write[index][2](io_mem_opaque[index], physaddr + 4, val >> 32);
>>  #endif
>>  #endif /* SHIFT > 2 */
>> -#ifdef USE_KQEMU
>> -    env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>  }
>>
>>  void REGPARM glue(glue(__st, SUFFIX), MMUSUFFIX)(target_ulong addr,
>> diff --git a/vl.c b/vl.c
>> index 964205d..e64becb 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -420,10 +420,7 @@ void cpu_outb(CPUState *env, int addr, int val)
>>         fprintf(logfile, "outb: %04x %02x\n", addr, val);
>>  #endif
>>     ioport_write(0, addr, val);
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>  }
>>
>>  void cpu_outw(CPUState *env, int addr, int val)
>> @@ -433,10 +430,7 @@ void cpu_outw(CPUState *env, int addr, int val)
>>         fprintf(logfile, "outw: %04x %04x\n", addr, val);
>>  #endif
>>     ioport_write(1, addr, val);
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>  }
>>
>>  void cpu_outl(CPUState *env, int addr, int val)
>> @@ -446,10 +440,7 @@ void cpu_outl(CPUState *env, int addr, int val)
>>         fprintf(logfile, "outl: %04x %08x\n", addr, val);
>>  #endif
>>     ioport_write(2, addr, val);
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>  }
>>
>>  int cpu_inb(CPUState *env, int addr)
>> @@ -460,10 +451,7 @@ int cpu_inb(CPUState *env, int addr)
>>     if (loglevel & CPU_LOG_IOPORT)
>>         fprintf(logfile, "inb : %04x %02x\n", addr, val);
>>  #endif
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>     return val;
>>  }
>>
>> @@ -475,10 +463,7 @@ int cpu_inw(CPUState *env, int addr)
>>     if (loglevel & CPU_LOG_IOPORT)
>>         fprintf(logfile, "inw : %04x %04x\n", addr, val);
>>  #endif
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>>     return val;
>>  }
>>
>> @@ -490,10 +475,7 @@ int cpu_inl(CPUState *env, int addr)
>>     if (loglevel & CPU_LOG_IOPORT)
>>         fprintf(logfile, "inl : %04x %08x\n", addr, val);
>>  #endif
>> -#ifdef USE_KQEMU
>> -    if (env)
>> -        env->last_io_time = cpu_get_time_fast();
>> -#endif
>> +    accel_trace_io(env);
>
> It would be great if all the new checks on the critical paths could
> remain wrapped in some kind of #ifdef for archs that don't have any
> acceleration implemented (also in other patches in this series).

Yeah, me and anthony were discussing exactly that, yesterday.
It's part of the plan now.



-- 
Glauber  Costa.
"Free as in Freedom"
http://glommer.net

"The less confident you are, the more serious you have to act."

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2008-10-25 11:14 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-23 14:18 [Qemu-devel] [PATCH 0/32] New shot at accelerators Glauber Costa
2008-10-23 13:35 ` [Qemu-devel] " Jan Kiszka
2008-10-23 14:07   ` Glauber Costa
2008-10-23 14:15     ` Avi Kivity
2008-10-23 13:44 ` Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
2008-10-23 13:35   ` [Qemu-devel] " Jan Kiszka
2008-10-23 13:48   ` Anthony Liguori
2008-10-23 14:17     ` Jan Kiszka
2008-10-23 14:25       ` Anthony Liguori
2008-10-23 15:08         ` Leonardo Reiter
2008-10-23 15:20           ` Leonardo Reiter
2008-10-24 19:30             ` Andreas Färber
2008-10-24 19:59               ` Ben Taylor
2008-10-25 10:17                 ` [Qemu-devel] QEMU on Solaris 10 (was: [PATCH 01/32] use anonymous memory for kqemu.) Andreas Färber
2008-10-25 10:27                   ` Andreas Färber
2008-10-25 10:45                     ` Blue Swirl
2008-10-24 15:37         ` [Qemu-devel] Re: [PATCH 01/32] use anonymous memory for kqemu Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 02/32] protect exec-all.h frm multiple inclusion Glauber Costa
2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 03/32] change definition of FILE for linux Glauber Costa
2008-10-23 13:52   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:13     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 04/32] move kqemu_cpu_exec to kqemu.c Glauber Costa
2008-10-23 13:55   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:21     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 05/32] use more meaningful values for kqemu_cpu_exec Glauber Costa
2008-10-23 13:57   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:23     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 06/32] split kqemu_init into two Glauber Costa
2008-10-23 13:58   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:28     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 07/32] introduce QEMUAccel and fill it with interrupt specific driver Glauber Costa
2008-10-23 14:00   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:18 ` [Qemu-devel] [PATCH 08/32] init env made accel driver Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 09/32] wrap cache flushing functions into accel drivers Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 10/32] turn info kqemu into generic info accelerator Glauber Costa
2008-10-23 14:03   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:24     ` Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 11/32] separate accelerator part of info profiler Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 12/32] move kqemu externs to kqemu.h Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 13/32] move disabling code to kqemu.c instead of vl.c Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 14/32] set_notdirty goes through accel wrapper Glauber Costa
2008-10-23 14:18 ` [Qemu-devel] [PATCH 15/32] wrap modify_page through accel calls Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 16/32] remove kqemu reference from hw/pc.c Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 17/32] build list of available accelerators Glauber Costa
2008-10-23 13:45   ` [Qemu-devel] " Avi Kivity
2008-10-23 15:09     ` Glauber Costa
2008-10-23 15:15       ` Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 18/32] provide --accel option Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 19/32] add hook to cpu_register_physical_memory Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 20/32] accel_trace_io Glauber Costa
2008-10-23 14:20   ` [Qemu-devel] " Anthony Liguori
2008-10-23 17:26     ` Glauber de Oliveira Costa
2008-10-25 11:10   ` [Qemu-devel] " andrzej zaborowski
2008-10-25 11:14     ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 21/32] get_env accel wrapper Glauber Costa
2008-10-23 13:36   ` [Qemu-devel] " Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 22/32] add next_cpu_index Glauber Costa
2008-10-23 14:21   ` [Qemu-devel] " Anthony Liguori
2008-10-23 14:37     ` Glauber Costa
2008-10-23 14:40       ` Jan Kiszka
2008-10-23 14:55         ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 23/32] move cpu_get_time_fast to kqemu.c Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 24/32] check wether kqemu is enabled in open code Glauber Costa
2008-10-23 13:38   ` [Qemu-devel] " Jan Kiszka
2008-10-23 14:49     ` Glauber Costa
2008-10-23 14:23   ` Anthony Liguori
2008-10-23 14:31     ` Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 25/32] provide accel hook for cpu_exec Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 26/32] provide two accelerators for kqemu Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 27/32] arch-specific hooks for accelerator Glauber Costa
2008-10-23 13:30   ` [Qemu-devel] " Avi Kivity
2008-10-23 13:35     ` Jan Kiszka
2008-10-23 13:47       ` Avi Kivity
2008-10-23 14:19 ` [Qemu-devel] [PATCH 28/32] iret arch specific accelerator Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 29/32] sysret/sysexit " Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 30/32] lcall/lret arch specific accel hooks Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 31/32] remove kqemu_is_ok tests Glauber Costa
2008-10-23 14:19 ` [Qemu-devel] [PATCH 32/32] clean up kqemu code Glauber Costa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).