qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Initial support for Ilumos build and Illumos-kv


From: Jan Kiszka
Subject: Re: [Qemu-devel] [PATCH] Initial support for Ilumos build and Illumos-kvm
Date: Fri, 16 Mar 2012 14:14:58 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686 (x86_64); de; rv:1.8.1.12) Gecko/20080226 SUSE/2.0.0.12-1.1 Thunderbird/2.0.0.12 Mnenhy/0.7.5.666

On 2012-03-16 10:23, Lee Essen wrote:
> This fixes a number of issues with the build process (namely ensuring the use 
> of bash), adds specific support for the Illumos port of KVM and fixes a few 
> general Solaris compatibility issues.
> 
> There are still some things outstanding:
> 
> - there's a duplicate smb_wmb() definition in qemu-barrier.h and the illumos 
> kvm_x86.h which generates some warnings.
> - there's a repeated call to page_size() that should probably be fixed.
> - dtrace support needs to be fixed (-m64/32 option, reserved words and 
> linking issues)
> - vnics need to be added
> - the original illumos code added another timer source (multiticks)
> - the issue with Linux needs to be resolved
> 
> Other than that, this gets it to the point where it will build and run with 
> illumos kvm, and works fine for Windows.
> 
> It's my first patch to qemu, and most of the real kvm stuff has come from the 
> original illumos-kvm-cmd tree, so be gentle with me!
> 
> 
> Signed-off-by: Lee Essen <address@hidden>
> 
> --
>  Makefile.objs              |    6 +-
>  Makefile.target            |    6 +-
>  configure                  |    8 +++-
>  cpus.c                     |    4 +-
>  exec.c                     |   88 
> ++++++++++++++++++++++++++++++++++++++++++++
>  fpu/softfloat-specialize.h |    4 ++
>  hw/kvm/clock.c             |    4 ++
>  kvm-all.c                  |   81 ++++++++++++++++++++++++++++++++++++++++-
>  kvm.h                      |   15 +++++++
>  qemu-timer.c               |   10 ++--
>  qga/channel-posix.c        |   16 ++++++++
>  qga/commands-posix.c       |    9 ++++
>  target-i386/hyperv.h       |    4 ++
>  target-i386/kvm.c          |   53 +++++++++++++++++++++++++-
>  14 files changed, 291 insertions(+), 17 deletions(-)
> 

...

> diff --git a/hw/kvm/clock.c b/hw/kvm/clock.c
> index 446bd62..3fd5e1e 100644
> --- a/hw/kvm/clock.c
> +++ b/hw/kvm/clock.c
> @@ -19,8 +19,12 @@
>  #include "hw/sysbus.h"
>  #include "hw/kvm/clock.h"
>  
> +#ifdef __sun__
> +#include <sys/kvm.h>
> +#else
>  #include <linux/kvm.h>
>  #include <linux/kvm_para.h>
> +#endif

As Paolo already said, this should somehow be centralized.

Also, CONFIG_SOLARIS vs. __sun__: please use a consistent pattern.

>  
>  typedef struct KVMClockState {
>      SysBusDevice busdev;
> diff --git a/kvm-all.c b/kvm-all.c
> index 42e5e23..27f3177 100644
> --- a/kvm-all.c
> +++ b/kvm-all.c
> @@ -18,7 +18,11 @@
>  #include <sys/mman.h>
>  #include <stdarg.h>
>  
> +#ifdef __sun__
> +#include <sys/kvm.h>
> +#else
>  #include <linux/kvm.h>
> +#endif
>  
>  #include "qemu-common.h"
>  #include "qemu-barrier.h"
> @@ -176,12 +180,23 @@ int kvm_physical_memory_addr_from_host(KVMState *s, 
> void *ram,
>  static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
>  {
>      struct kvm_userspace_memory_region mem;
> +#ifdef CONFIG_SOLARIS
> +    caddr_t p;
> +    char c;
> +#endif
>  
>      mem.slot = slot->slot;
>      mem.guest_phys_addr = slot->start_addr;
>      mem.memory_size = slot->memory_size;
>      mem.userspace_addr = (unsigned long)slot->ram;
>      mem.flags = slot->flags;
> +#ifdef CONFIG_SOLARIS
> +    for (p = (caddr_t)mem.userspace_addr;
> +      p < (caddr_t)mem.userspace_addr + mem.memory_size;
> +      p += PAGE_SIZE)
> +        c = *p;
> +#endif /* CONFIG_SOLARIS */
> +

I bet gcc will like this write-only pattern and bark at you.

>      if (s->migration_log) {
>          mem.flags |= KVM_MEM_LOG_DIRTY_PAGES;
>      }
> @@ -200,6 +215,31 @@ int kvm_pit_in_kernel(void)
>      return kvm_state->pit_in_kernel;
>  }
>  
> +#ifdef CONFIG_SOLARIS
> +static int kvm_vm_clone(KVMState *s)
> +{
> +    struct stat stat;
> +    int fd;
> +
> +    if (fstat(s->fd, &stat) != 0) {
> +        return -errno;
> +    }
> +
> +    fd = qemu_open("/dev/kvm", O_RDWR);
> +
> +    if (fd == -1) {
> +        return -errno;
> +    }
> +
> +    if (ioctl(fd, KVM_CLONE, stat.st_rdev) == -1) {
> +        close(fd);
> +        return -errno;
> +    }
> +
> +    return fd;
> +}
> +#endif
> +
>  int kvm_init_vcpu(CPUArchState *env)
>  {
>      KVMState *s = kvm_state;
> @@ -208,14 +248,29 @@ int kvm_init_vcpu(CPUArchState *env)
>  
>      DPRINTF("kvm_init_vcpu\n");
>  
> +#ifdef CONFIG_SOLARIS
> +    ret = kvm_vm_clone(kvm_state);
> +
> +    if (ret < 0) {
> +        fprintf(stderr, "kvm_init_vcpu could not clone fd: %m\n");
> +        goto err;
> +    }
> +    env->kvm_fd = ret;
> +    env->kvm_state = kvm_state;
> +
> +    ret = ioctl(env->kvm_fd, KVM_CREATE_VCPU, env->cpu_index);

kvm_vcpu_ioctl

> +#else
>      ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index);
> +#endif

There is no chance to fix the Solaris KVM to do fd cloning in the kernel
and implement the same KVM_CREATE_VCPU ABI?

>      if (ret < 0) {
>          DPRINTF("kvm_create_vcpu failed\n");
>          goto err;
>      }
>  
> +#ifndef CONFIG_SOLARIS
>      env->kvm_fd = ret;
>      env->kvm_state = s;
> +#endif
>      env->kvm_vcpu_dirty = 1;
>  
>      mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
> @@ -1021,6 +1076,9 @@ int kvm_init(void)
>          ret = s->vmfd;
>          goto err;
>      }
> +#ifdef CONFIG_SOLARIS
> +    s->vmfd = s->fd;
> +#endif
>  
>      missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);
>      if (!missing_cap) {
> @@ -1287,6 +1345,19 @@ int kvm_cpu_exec(CPUArchState *env)
>              DPRINTF("irq_window_open\n");
>              ret = EXCP_INTERRUPT;
>              break;
> +#ifdef CONFIG_SOLARIS
> +        /*
> +         * In the case of an external interrupt we can get a zero
> +         * return from the ioctl, with a KVM_EXIT_INTR. This doesn't
> +         * happen on linux
> +         *
> +         * Not entirely sure what to do here.

Fix the kernel?

> +         */
> +        case KVM_EXIT_INTR:
> +            DPRINTF("exit_intr (run_ret is %d)\n", run_ret);
> +            ret = EXCP_INTERRUPT;
> +            break;
> +#endif
>          case KVM_EXIT_SHUTDOWN:
>              DPRINTF("shutdown\n");
>              qemu_system_reset_request();
> @@ -1631,7 +1702,7 @@ int kvm_set_signal_mask(CPUArchState *env, const 
> sigset_t *sigset)
>  
>      sigmask = g_malloc(sizeof(*sigmask) + sizeof(*sigset));
>  
> -    sigmask->len = 8;
> +    sigmask->len = sizeof(sigset_t);
>      memcpy(sigmask->sigset, sigset, sizeof(*sigset));
>      r = kvm_vcpu_ioctl(env, KVM_SET_SIGNAL_MASK, sigmask);
>      g_free(sigmask);
> @@ -1641,6 +1712,7 @@ int kvm_set_signal_mask(CPUArchState *env, const 
> sigset_t *sigset)
>  
>  int kvm_set_ioeventfd_mmio_long(int fd, uint32_t addr, uint32_t val, bool 
> assign)
>  {
> +#ifdef CONFIG_EVENTFD
>      int ret;
>      struct kvm_ioeventfd iofd;
>  
> @@ -1665,10 +1737,14 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t 
> addr, uint32_t val, bool assign
>      }
>  
>      return 0;
> +#else
> +    return -ENOSYS;
> +#endif
>  }
>  
>  int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool 
> assign)
>  {
> +#ifdef CONFIG_EVENTFD
>      struct kvm_ioeventfd kick = {
>          .datamatch = val,
>          .addr = addr,
> @@ -1688,6 +1764,9 @@ int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, 
> uint16_t val, bool assign)
>          return r;
>      }
>      return 0;
> +#else
> +    return -ENOSYS;
> +#endif
>  }
>  
>  int kvm_on_sigbus_vcpu(CPUArchState *env, int code, void *addr)
> diff --git a/kvm.h b/kvm.h
> index 330f17b..8960b4e 100644
> --- a/kvm.h
> +++ b/kvm.h
> @@ -19,8 +19,23 @@
>  #include "qemu-queue.h"
>  
>  #ifdef CONFIG_KVM
> +#ifdef __sun__
> +#include <sys/kvm.h>
> +/*
> + * it's a bit horrible to include these here, but the kvm_para.h include file
> + * isn't public with the illumos kvm implementation

Just provide a package of properly fixed kernel headers and let us carry
them in solaris-headers or so, analogously to linux-headers.

> + */
> +#define KVM_CPUID_SIGNATURE       0x40000000
> +#define KVM_CPUID_FEATURES        0x40000001
> +#define KVM_FEATURE_CLOCKSOURCE   0
> +#define KVM_FEATURE_NOP_IO_DELAY  1
> +#define KVM_FEATURE_MMU_OP        2
> +#define KVM_FEATURE_CLOCKSOURCE2  3
> +#define HYPERV_CPUID_MIN          0x40000005
> +#else
>  #include <linux/kvm.h>
>  #endif
> +#endif
>  
>  extern int kvm_allowed;
>  extern bool kvm_kernel_irqchip;

...

> diff --git a/target-i386/kvm.c b/target-i386/kvm.c
> index e74a9e4..6d007cc 100644
> --- a/target-i386/kvm.c
> +++ b/target-i386/kvm.c
> @@ -17,8 +17,12 @@
>  #include <sys/mman.h>
>  #include <sys/utsname.h>
>  
> +#ifdef __sun__
> +#include <sys/kvm.h>
> +#else
>  #include <linux/kvm.h>
>  #include <linux/kvm_para.h>
> +#endif
>  
>  #include "qemu-common.h"
>  #include "sysemu.h"
> @@ -61,7 +65,9 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
>  static bool has_msr_star;
>  static bool has_msr_hsave_pa;
>  static bool has_msr_tsc_deadline;
> +#ifdef KVM_CAP_ASYNC_PF
>  static bool has_msr_async_pf_en;
> +#endif

NACK. With proper kernel headers, all these KVM_CAP reintroductions
become obsolete again.

Note that KVM changes need to CC the kvm mailing list and will likely
flow via uq/master of qemu-kvm.git.

Jan

-- 
Siemens AG, Corporate Technology, CT T DE IT 1
Corporate Competence Center Embedded Linux



reply via email to

[Prev in Thread] Current Thread [Next in Thread]