Il 16/03/2012 10:23, Lee Essen ha scritto: > diff --git a/Makefile.objs b/Makefile.objs > index 226b01d..c2a440a 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -373,12 +373,12 @@ else > trace.h: trace.h-timestamp > endif > trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak > - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h") > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h") > @cmp -s $@ trace.h || cp $@ trace.h > > trace.c: trace.c-timestamp > trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak > - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c") > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c") > @cmp -s $@ trace.c || cp $@ trace.c > > trace.o: trace.c $(GENERATED_HEADERS) > @@ -391,7 +391,7 @@ trace-dtrace.h: trace-dtrace.dtrace > # rule file. So we use '.dtrace' instead > trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp > trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events > $(BUILD_DIR)/config-host.mak > - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace") > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/tracetool > --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace") > @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace > > trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS) > diff --git a/Makefile.target b/Makefile.target > index eb25941..d32afc9 100644 > --- a/Makefile.target > +++ b/Makefile.target > @@ -59,7 +59,7 @@ TARGET_TYPE=system > endif > > $(QEMU_PROG).stp: > - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool \ > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/tracetool \ > --$(TRACE_BACKEND) \ > --binary $(bindir)/$(QEMU_PROG) \ > --target-arch $(TARGET_ARCH) \ > @@ -443,10 +443,10 @@ gdbstub-xml.c: $(TARGET_XML_FILES) > $(SRC_PATH)/scripts/feature_to_c.sh > $(call quiet-command,rm -f $@ && $(SHELL) > $(SRC_PATH)/scripts/feature_to_c.sh $@ $(TARGET_XML_FILES)," GEN > $(TARGET_DIR)$@") > > hmp-commands.h: $(SRC_PATH)/hmp-commands.hx > - $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > > $@," GEN $(TARGET_DIR)$@") > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/hxtool -h < $< >> $@," GEN $(TARGET_DIR)$@") > > qmp-commands-old.h: $(SRC_PATH)/qmp-commands.hx > - $(call quiet-command,sh $(SRC_PATH)/scripts/hxtool -h < $< > > $@," GEN $(TARGET_DIR)$@") > + $(call quiet-command,$(SHELL) $(SRC_PATH)/scripts/hxtool -h < $< >> $@," GEN $(TARGET_DIR)$@") > > clean: > rm -f *.o *.a *~ $(PROGS) nwfpe/*.o fpu/*.o > diff --git a/configure b/configure > index afe7395..601f77a 100755 > --- a/configure > +++ b/configure > @@ -101,6 +101,7 @@ audio_win_int="" > cc_i386=i386-pc-linux-gnu-gcc > libs_qga="" > debug_info="yes" > +shell="sh" > > target_list="" > > @@ -442,6 +443,7 @@ SunOS) > # have to select again, because `uname -m` returns i86pc > # even on an x86_64 box. > solariscpu=`isainfo -k` > + shell="bash" > if test "${solariscpu}" = "amd64" ; then > cpu="x86_64" > fi > @@ -471,6 +473,7 @@ SunOS) > QEMU_CFLAGS="-D__EXTENSIONS__ $QEMU_CFLAGS" > QEMU_CFLAGS="-std=gnu99 $QEMU_CFLAGS" > LIBS="-lsocket -lnsl -lresolv $LIBS" > + libs_qga="-lsocket -lxnet $lib_qga" > ;; > AIX) > aix="yes" > @@ -1097,7 +1100,7 @@ echo " --disable-docs disable > documentation build" > echo " --disable-vhost-net disable vhost-net acceleration support" > echo " --enable-vhost-net enable vhost-net acceleration support" > echo " --enable-trace-backend=B Set trace backend" > -echo " Available backends:" > $("$source_path"/scripts/tracetool --list-backends) > +echo " Available backends:" $($shell > "$source_path"/scripts/tracetool --list-backends) > echo " --with-trace-file=NAME Full PATH,NAME of file to store traces" > echo " Default:trace-<pid>" > echo " --disable-spice disable spice" > @@ -2654,7 +2657,7 @@ fi > ########################################## > # check if trace backend exists > > -sh "$source_path/scripts/tracetool" "--$trace_backend" --check-backend >> /dev/null 2> /dev/null > +$shell "$source_path/scripts/tracetool" "--$trace_backend" > --check-backend > /dev/null 2> /dev/null > if test "$?" -ne 0 ; then > echo > echo "Error: invalid trace backend" > @@ -3358,6 +3361,7 @@ echo "LIBS+=$LIBS" >> $config_host_mak > echo "LIBS_TOOLS+=$libs_tools" >> $config_host_mak > echo "EXESUF=$EXESUF" >> $config_host_mak > echo "LIBS_QGA+=$libs_qga" >> $config_host_mak > +echo "SHELL=$shell" >> $config_host_mak > > # generate list of library paths for linker script > > diff --git a/cpus.c b/cpus.c
Everything up to here should be a separate patch, but it looks sane. > index 25ba621..7a32ee6 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -455,7 +455,7 @@ static void cpu_signal(int sig) > exit_request = 1; > } > > -#ifdef CONFIG_LINUX > +#if defined(CONFIG_LINUX) || defined(CONFIG_SOLARIS) > static void sigbus_reraise(void) > { > sigset_t set; > @@ -491,7 +491,9 @@ static void qemu_init_sigbus(void) > action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler; > sigaction(SIGBUS, &action, NULL); > > +#ifndef __sun__ > prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0); > +#endif > } > > static void qemu_kvm_eat_signals(CPUArchState *env) > diff --git a/exec.c b/exec.c > index 8fd50a1..57e2890 100644 > --- a/exec.c > +++ b/exec.c > @@ -2853,6 +2853,79 @@ static ram_addr_t last_ram_offset(void) > return last; > } > > +#ifdef CONFIG_SOLARIS > +static int > +qemu_mlock(caddr_t base, ram_addr_t size) > +{ > + /* LEE - todo */ > + qemu_real_host_page_size = getpagesize(); > + > + ram_addr_t ps = qemu_real_host_page_size, nbytes, locked = 0; > + ram_addr_t remaining = size / ps; > + ram_addr_t step = remaining; > + timespec_t tv; > + hrtime_t waiting = 0, threshold; > + > + tv.tv_sec = 0; > + tv.tv_nsec = NANOSEC / MILLISEC; > + threshold = 10 * (hrtime_t)NANOSEC; > + > + /* > + * We cannot lock memory with a single call to mlock() because it > + * won't result in sustained memory pressure: if there is a > + * substantial amount of kernel memory in use electively (e.g., for > + * the ARC) a single call to mlock() may fail where sustained memory > + * pressure would succeed. We therefore start by trying to lock the > + * entire region, adjusting our size down as we fail with EAGAIN; once > + * we successfully lock a portion of the region, we advance to the > + * unlocked portion of the region (if any remains) and increase the > + * size. Note that this will continue to hoard memory until it locks > + * what it needs -- it won't give up. To help debug situations in > + * which one has mistakenly overprovisioned, we emit a message every > + * ten seconds with no forward progress. > + */ > + while (remaining) { > + if (step > remaining) { > + step = remaining; > + } > + > + while (mlock(base, (nbytes = step * ps)) == -1) { > + if (errno != EAGAIN) { > + return -1; > + } > + > + if (waiting == 0) { > + waiting = gethrtime(); Please use qemu_get_clock_ns(rt_clock) here. > + } > + > + if (step > 1) { > + step >>= 1; > + continue; > + } > + > + (void) nanosleep(&tv, NULL); > + > + if (gethrtime() - waiting > threshold) { > + (void) fprintf(stderr, "qemu_mlock: have only " > + "locked %ld of %ld bytes; still " > + "trying...\n", locked, size); > + waiting = 0; > + } > + } > + > + waiting = 0; > + base += nbytes; > + locked += nbytes; > + remaining -= step; > + > + step <<= 1; > + } > + > + return 0; > +} > +#endif > + > + > void qemu_ram_set_idstr(ram_addr_t addr, const char *name, DeviceState > *dev) > { > RAMBlock *new_block, *block; > @@ -2931,6 +3004,21 @@ ram_addr_t qemu_ram_alloc_from_ptr(ram_addr_t > size, void *host, > new_block->host = qemu_vmalloc(size); > } > #endif > + > +#ifdef CONFIG_SOLARIS > + /* > + * XXX For right now, we'll lock down the memory. This needs > + * to be revisited if we implement mmu notifiers in the > kernel. > + * Note also that pages are touched in > kvm_set_user_memory_region. > + */ > + if (qemu_mlock((caddr_t)new_block->host, size) != 0) { > + fprintf(stderr, "qemu_ram_alloc: Could not lock %ld > memory," > + " errno = %d\n", > + size, errno); > + exit(1); > + } > +#endif /*CONFIG_SOLARIS*/ > + > qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE); > } > } > diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h > index c5e2dab..3889041 100644 > --- a/fpu/softfloat-specialize.h > +++ b/fpu/softfloat-specialize.h > @@ -89,8 +89,10 @@ const float64 float64_default_nan = > const_float64(LIT64( 0xFFF8000000000000 )); > #define floatx80_default_nan_low LIT64( 0xC000000000000000 ) > #endif > > +#ifndef __sun__ > const floatx80 floatx80_default_nan = > make_floatx80(floatx80_default_nan_high, > > floatx80_default_nan_low); > +#endif Why is this needed. > > > /*---------------------------------------------------------------------------- > | The pattern for a default generated quadruple-precision NaN. The > `high' and > @@ -104,8 +106,10 @@ const floatx80 floatx80_default_nan = > make_floatx80(floatx80_default_nan_high, > #define float128_default_nan_low LIT64( 0x0000000000000000 ) > #endif > > +#ifndef __sun__ > const float128 float128_default_nan = > make_float128(float128_default_nan_high, > > float128_default_nan_low); > +#endif > > > /*---------------------------------------------------------------------------- > | Raises the exceptions specified by `flags'. Floating-point traps can be > 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 Perhaps you can put this in kvm.h instead, and just include that file: #ifdef __sun__ #include <sys/kvm.h> #else #include <linux/kvm.h> #endif #include <linux/kvm_para.h> kvm_para.h should be independent of the host OS, hoping there's no conflict between Solaris and Linux headers. > > 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 */ What is this needed for? > + > 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); > +#else > ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index); > +#endif > 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_state assignment need not be split, right? > 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. > + */ > + 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 The guard probably needs to be added also around ioeventfd definitions in virtio-pci.c. > } > > 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 > + */ > +#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/qemu-timer.c b/qemu-timer.c > index d7f56e5..f35ad4e 100644 > --- a/qemu-timer.c > +++ b/qemu-timer.c > @@ -77,7 +77,7 @@ struct qemu_alarm_timer { > int (*start)(struct qemu_alarm_timer *t); > void (*stop)(struct qemu_alarm_timer *t); > void (*rearm)(struct qemu_alarm_timer *t, int64_t nearest_delta_ns); > -#if defined(__linux__) > +#if defined(__linux__) || defined(__sun__) Starting from here it would also be a separate patch. Perhaps you can add a configure test for timer_t instead. > int fd; > timer_t timer; > #elif defined(_WIN32) > @@ -165,7 +165,7 @@ static int unix_start_timer(struct qemu_alarm_timer *t); > static void unix_stop_timer(struct qemu_alarm_timer *t); > static void unix_rearm_timer(struct qemu_alarm_timer *t, int64_t delta); > > -#ifdef __linux__ > +#if defined(__linux__) || defined(__sun__) > > static int dynticks_start_timer(struct qemu_alarm_timer *t); > static void dynticks_stop_timer(struct qemu_alarm_timer *t); > @@ -177,7 +177,7 @@ static void dynticks_rearm_timer(struct > qemu_alarm_timer *t, int64_t delta); > > static struct qemu_alarm_timer alarm_timers[] = { > #ifndef _WIN32 > -#ifdef __linux__ > +#if defined(__linux__) || defined(__sun__) > {"dynticks", dynticks_start_timer, > dynticks_stop_timer, dynticks_rearm_timer}, > #endif > @@ -502,7 +502,7 @@ static void host_alarm_handler(int host_signum) > } > } > > -#if defined(__linux__) > +#if defined(__linux__) || defined(__sun__) > > #include "compatfd.h" > > @@ -585,7 +585,7 @@ static void dynticks_rearm_timer(struct > qemu_alarm_timer *t, > } > } > > -#endif /* defined(__linux__) */ > +#endif /* defined(__linux__) || defined(__sun__) */ > > #if !defined(_WIN32) > > diff --git a/qga/channel-posix.c b/qga/channel-posix.c > index 40f7658..86245c1 100644 > --- a/qga/channel-posix.c > +++ b/qga/channel-posix.c > @@ -3,6 +3,10 @@ > #include "qemu_socket.h" > #include "qga/channel.h" > > +#ifdef CONFIG_SOLARIS > +#include <sys/stropts.h> > +#endif > + > #define GA_CHANNEL_BAUDRATE_DEFAULT B38400 /* for isa-serial channels */ > > struct GAChannel { Starting from here it would also be a separate patch. > @@ -123,7 +127,19 @@ static gboolean ga_channel_open(GAChannel *c, const > gchar *path, GAChannelMethod > > switch (c->method) { > case GA_CHANNEL_VIRTIO_SERIAL: { > +#ifdef CONFIG_SOLARIS > + int fd = qemu_open(path, O_RDWR | O_NONBLOCK); > + if (fd == -1) { > + g_critical("error opening channel: %s", strerror(errno)); > + exit(EXIT_FAILURE); > + } > + if (ioctl(fd, I_SETSIG, S_OUTPUT | S_INPUT | S_HIPRI) < 0) { > + g_critical("error with setsig on channel: %s", > strerror(errno)); > + exit(EXIT_FAILURE); > + } > +#else > int fd = qemu_open(path, O_RDWR | O_NONBLOCK | O_ASYNC); > +#endif > if (fd == -1) { > g_critical("error opening channel: %s", strerror(errno)); > exit(EXIT_FAILURE); > diff --git a/qga/commands-posix.c b/qga/commands-posix.c > index 7b2be2f..67531aa 100644 > --- a/qga/commands-posix.c > +++ b/qga/commands-posix.c > @@ -35,6 +35,11 @@ > #include "qemu-queue.h" > #include "host-utils.h" > > +#if defined(__sun__) > +#include <sys/sockio.h> > +extern char **environ; > +#endif > + > static void reopen_fd_to_null(int fd) > { > int nullfd; > @@ -807,7 +812,11 @@ GuestNetworkInterfaceList > *qmp_guest_network_get_interfaces(Error **errp) > goto error; > } > > +#if defined(__sun__) > + mac_addr = (unsigned char *) &ifr.ifr_enaddr; > +#else > mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; > +#endif > > if (asprintf(&info->value->hardware_address, > "%02x:%02x:%02x:%02x:%02x:%02x", > diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h > index bacb1d4..9c08750 100644 > --- a/target-i386/hyperv.h > +++ b/target-i386/hyperv.h > @@ -15,8 +15,12 @@ > > #include "qemu-common.h" > #ifdef CONFIG_KVM > +#ifdef __sun__ > +#include <hyperv.h> > +#else > #include <asm/hyperv.h> > #endif > +#endif > > #ifndef HYPERV_SPINLOCK_NEVER_RETRY > #define HYPERV_SPINLOCK_NEVER_RETRY 0xFFFFFFFF > 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 > static bool has_msr_misc_enable; > static int lm_capable_kernel; > > @@ -97,7 +103,9 @@ struct kvm_para_features { > { KVM_CAP_CLOCKSOURCE, KVM_FEATURE_CLOCKSOURCE }, > { KVM_CAP_NOP_IO_DELAY, KVM_FEATURE_NOP_IO_DELAY }, > { KVM_CAP_PV_MMU, KVM_FEATURE_MMU_OP }, > +#ifdef KVM_CAP_ASYNC_PF > { KVM_CAP_ASYNC_PF, KVM_FEATURE_ASYNC_PF }, > +#endif > { -1, -1 } > }; > > @@ -442,7 +450,9 @@ int kvm_arch_init_vcpu(CPUX86State *env) > c->edx = signature[2]; > } > > +#ifdef KVM_CAP_ASYNC_PF > has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); > +#endif > > cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); > > @@ -561,6 +571,7 @@ int kvm_arch_init_vcpu(CPUX86State *env) > return r; > } > > +#ifdef KVM_CAP_TSC_CONTROL > r = kvm_check_extension(env->kvm_state, KVM_CAP_TSC_CONTROL); > if (r && env->tsc_khz) { > r = kvm_vcpu_ioctl(env, KVM_SET_TSC_KHZ, env->tsc_khz); > @@ -569,10 +580,12 @@ int kvm_arch_init_vcpu(CPUX86State *env) > return r; > } > } > - > +#endif > +#ifdef KVM_CAP_XSAVE > if (kvm_has_xsave()) { > env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); > } > +#endif > > return 0; > } > @@ -759,7 +772,7 @@ static void get_seg(SegmentCache *lhs, const struct > kvm_segment *rhs) > (rhs->avl * DESC_AVL_MASK); > } > > -static void kvm_getput_reg(__u64 *kvm_reg, target_ulong *qemu_reg, int set) > +static void kvm_getput_reg(uint64_t *kvm_reg, target_ulong *qemu_reg, > int set) > { > if (set) { > *kvm_reg = *qemu_reg; > @@ -841,6 +854,7 @@ static int kvm_put_fpu(CPUX86State *env) > #define XSAVE_XSTATE_BV 128 > #define XSAVE_YMMH_SPACE 144 > > +#ifdef KVM_CAP_XSAVE > static int kvm_put_xsave(CPUX86State *env) > { > struct kvm_xsave* xsave = env->kvm_xsave_buf; > @@ -874,7 +888,9 @@ static int kvm_put_xsave(CPUX86State *env) > r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave); > return r; > } > +#endif > > +#ifdef KVM_CAP_XSCRS > static int kvm_put_xcrs(CPUX86State *env) > { > struct kvm_xcrs xcrs; > @@ -889,6 +905,7 @@ static int kvm_put_xcrs(CPUX86State *env) > xcrs.xcrs[0].value = env->xcr0; > return kvm_vcpu_ioctl(env, KVM_SET_XCRS, &xcrs); > } > +#endif > > static int kvm_put_sregs(CPUX86State *env) > { > @@ -1000,10 +1017,12 @@ static int kvm_put_msrs(CPUX86State *env, int level) > kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME, > env->system_time_msr); > kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, > env->wall_clock_msr); > +#ifdef KVM_CAP_ASYNC_PF > if (has_msr_async_pf_en) { > kvm_msr_entry_set(&msrs[n++], MSR_KVM_ASYNC_PF_EN, > env->async_pf_en_msr); > } > +#endif > if (hyperv_hypercall_available()) { > kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_GUEST_OS_ID, 0); > kvm_msr_entry_set(&msrs[n++], HV_X64_MSR_HYPERCALL, 0); > @@ -1055,6 +1074,7 @@ static int kvm_get_fpu(CPUX86State *env) > return 0; > } > > +#ifdef KVM_CAP_XSAVE > static int kvm_get_xsave(CPUX86State *env) > { > struct kvm_xsave* xsave = env->kvm_xsave_buf; > @@ -1092,7 +1112,9 @@ static int kvm_get_xsave(CPUX86State *env) > sizeof env->ymmh_regs); > return 0; > } > +#endif > > +#ifdef KVM_CAP_XCRS > static int kvm_get_xcrs(CPUX86State *env) > { > int i, ret; > @@ -1116,6 +1138,7 @@ static int kvm_get_xcrs(CPUX86State *env) > } > return 0; > } > +#endif > > static int kvm_get_sregs(CPUX86State *env) > { > @@ -1243,9 +1266,11 @@ static int kvm_get_msrs(CPUX86State *env) > #endif > msrs[n++].index = MSR_KVM_SYSTEM_TIME; > msrs[n++].index = MSR_KVM_WALL_CLOCK; > +#ifdef KVM_CAP_ASYNC_PF > if (has_msr_async_pf_en) { > msrs[n++].index = MSR_KVM_ASYNC_PF_EN; > } > +#endif > > if (env->mcg_cap) { > msrs[n++].index = MSR_MCG_STATUS; > @@ -1322,9 +1347,11 @@ static int kvm_get_msrs(CPUX86State *env) > env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data; > } > break; > +#ifdef KVM_CAP_ASYNC_PF > case MSR_KVM_ASYNC_PF_EN: > env->async_pf_en_msr = msrs[i].data; > break; > +#endif > } > } > > @@ -1482,6 +1509,7 @@ static int kvm_guest_debug_workarounds(CPUX86State > *env) > return ret; > } > > +#ifdef KVM_CAP_DEBUGREGS > static int kvm_put_debugregs(CPUX86State *env) > { > struct kvm_debugregs dbgregs; > @@ -1522,6 +1550,7 @@ static int kvm_get_debugregs(CPUX86State *env) > > return 0; > } > +#endif > > int kvm_arch_put_registers(CPUX86State *env, int level) > { > @@ -1533,14 +1562,20 @@ int kvm_arch_put_registers(CPUX86State *env, int > level) > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_XSAVE > ret = kvm_put_xsave(env); > +#else > + ret = kvm_put_fpu(env); > +#endif > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_XCRS > ret = kvm_put_xcrs(env); > if (ret < 0) { > return ret; > } > +#endif > ret = kvm_put_sregs(env); > if (ret < 0) { > return ret; > @@ -1568,10 +1603,12 @@ int kvm_arch_put_registers(CPUX86State *env, int > level) > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_DEBUGREGS > ret = kvm_put_debugregs(env); > if (ret < 0) { > return ret; > } > +#endif > /* must be last */ > ret = kvm_guest_debug_workarounds(env); > if (ret < 0) { > @@ -1590,14 +1627,20 @@ int kvm_arch_get_registers(CPUX86State *env) > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_XSAVE > ret = kvm_get_xsave(env); > +#else > + ret = kvm_get_fpu(env); > +#endif > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_XCRS > ret = kvm_get_xcrs(env); > if (ret < 0) { > return ret; > } > +#endif > ret = kvm_get_sregs(env); > if (ret < 0) { > return ret; > @@ -1618,10 +1661,12 @@ int kvm_arch_get_registers(CPUX86State *env) > if (ret < 0) { > return ret; > } > +#ifdef KVM_CAP_DEBUGREGS > ret = kvm_get_debugregs(env); > if (ret < 0) { > return ret; > } > +#endif > return 0; > } > > @@ -1770,6 +1815,7 @@ static int kvm_handle_tpr_access(CPUX86State *env) > return 1; > } > > +#ifdef KVM_CAP_SET_GUEST_DEBUG > int kvm_arch_insert_sw_breakpoint(CPUX86State *env, struct > kvm_sw_breakpoint *bp) > { > static const uint8_t int3 = 0xcc; > @@ -1950,6 +1996,7 @@ void kvm_arch_update_guest_debug(CPUX86State *env, > struct kvm_guest_debug *dbg) > } > } > } > +#endif /* KVM_CAP_SET_GUEST_DEBUG */ > > static bool host_supports_vmx(void) > { > @@ -1999,10 +2046,12 @@ int kvm_arch_handle_exit(CPUX86State *env, > struct kvm_run *run) > run->ex.exception, run->ex.error_code); > ret = -1; > break; > +#ifdef KVM_CAP_SET_GUEST_DEBUG > case KVM_EXIT_DEBUG: > DPRINTF("kvm_exit_debug\n"); > ret = kvm_handle_debug(&run->debug.arch); > break; > +#endif > default: > fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason); > ret = -1; > Did you have any problem with IOV_MAX? IIRC, it's quite low (16 perhaps) in Solaris. Paolo