Skip to contentSkip to conversation

qemu-kvm.git uq/master queue

GIT PULL New Marcelo Tosatti 2 participants 13 messages Oct 19, 2010

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

The following changes since commit 38cc9b607f85017b095793cab6c129bc9844f441:

issue snd_pcm_start() when capturing audio (2010-10-18 00:39:06 +0400)

are available in the git repository at:
git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master

Huang Ying (1):

      Add RAM -> physical addr mapping in MCE simulation

Joerg Roedel (2):
Set cpuid definition to 0 before initializing it Add svm cpuid features

Marcelo Tosatti (7):
signalfd compatibility
iothread: use signalfd
Expose thread_id in info cpus
kvm: x86: add mce support
Export qemu_ram_addr_from_host
MCE: Relay UCR MCE to guest
Add savevm/loadvm support for MCE

 Makefile.objs         |    1 +
 compatfd.c            |  117 +++++++++++++++++++
 compatfd.h            |   43 +++++++
 configure             |   18 +++
 cpu-common.h          |    3 +-
 cpu-defs.h            |    1 +
 cpus.c                |  161 ++++++++++++++++++++++++--
 exec-all.h            |    2 +-
 exec.c                |   27 +++--
 kvm-all.c             |   18 +++
 kvm-stub.c            |    5 +
 kvm.h                 |    6 +
 monitor.c             |    4 +
 osdep.c               |   15 +++
 osdep.h               |    1 +
 target-i386/cpu.h     |   32 +++++-
 target-i386/cpuid.c   |   79 ++++++++++---
 target-i386/helper.c  |    6 +
 target-i386/kvm.c     |  300 ++++++++++++++++++++++++++++++++++++++++++++++++-
 target-i386/kvm_x86.h |   22 ++++
 20 files changed, 817 insertions(+), 44 deletions(-)
 create mode 100644 compatfd.c
 create mode 100644 compatfd.h
 create mode 100644 target-i386/kvm_x86.h
#1 lore raw

PATCH 1/10 Set cpuid definition to 0 before initializing it

From: Joerg Roedel <[email protected]>

This patch cleans the (stack-allocated) cpuid definition to 0 before actually initializing it.

---
 target-i386/cpuid.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)
target-i386/cpuid.c +2 -0
index 04ba8d5..3fcf78f 100644
@@ -788,6 +788,8 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
 {
     x86_def_t def1, *def = &def1;
 
+    memset(def, 0, sizeof(*def));
+
     if (cpu_x86_find_by_name(def, cpu_model) < 0)
         return -1;
     if (def->vendor1) {
Signature · 1 line
1.7.2.1
#2 lore raw

PATCH 2/10 Add svm cpuid features

In reply to Marcelo Tosatti

From: Joerg Roedel <[email protected]>

This patch adds the svm cpuid feature flags to the qemu intialization path. It also adds the svm features available on phenom to its cpu-definition and extends the host cpu type to support all svm features KVM can provide.

---
 target-i386/cpu.h   |   12 ++++++++
 target-i386/cpuid.c |   77 +++++++++++++++++++++++++++++++++++++++-----------
 target-i386/kvm.c   |    3 ++
 3 files changed, 75 insertions(+), 17 deletions(-)
target-i386/cpu.h +12 -0
index 1144d4e..77eeab1 100644
@@ -405,6 +405,17 @@
 #define CPUID_EXT3_IBS     (1 << 10)
 #define CPUID_EXT3_SKINIT  (1 << 12)
 
+#define CPUID_SVM_NPT          (1 << 0)
+#define CPUID_SVM_LBRV         (1 << 1)
+#define CPUID_SVM_SVMLOCK      (1 << 2)
+#define CPUID_SVM_NRIPSAVE     (1 << 3)
+#define CPUID_SVM_TSCSCALE     (1 << 4)
+#define CPUID_SVM_VMCBCLEAN    (1 << 5)
+#define CPUID_SVM_FLUSHASID    (1 << 6)
+#define CPUID_SVM_DECODEASSIST (1 << 7)
+#define CPUID_SVM_PAUSEFILTER  (1 << 10)
+#define CPUID_SVM_PFTHRESHOLD  (1 << 12)
+
 #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
 #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
 #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
@@ -702,6 +713,7 @@ typedef struct CPUX86State {
     uint8_t has_error_code;
     uint32_t sipi_vector;
     uint32_t cpuid_kvm_features;
+    uint32_t cpuid_svm_features;
     
     /* in order to simplify APIC support, we leave this pointer to the
        user */
target-i386/cpuid.c +60 -17

172 lines not on this page · raw message

target-i386/kvm.c +3 -0
index a33d2fa..74e7b4f 100644
@@ -192,6 +192,9 @@ int kvm_arch_init_vcpu(CPUState *env)
                                                              0, R_EDX);
     env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
                                                              0, R_ECX);
+    env->cpuid_svm_features  &= kvm_arch_get_supported_cpuid(env, 0x8000000A,
+                                                             0, R_EDX);
+
 
     cpuid_i = 0;
 
Signature · 1 line
1.7.2.1
#3 lore raw

PATCH 3/10 signalfd compatibility

In reply to Marcelo Tosatti

Port qemu-kvm's signalfd compat code.

commit 5a7fdd0abd7cd24dac205317a4195446ab8748b5

Author: Anthony Liguori <[email protected]>
Date:   Wed May 7 11:55:47 2008 -0500

Use signalfd() in io-thread

This patch reworks the IO thread to use signalfd() instead of sigtimedwait() This will eliminate the need to use SIGIO everywhere.

---
 Makefile.objs |    1 +
 compatfd.c    |  117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 compatfd.h    |   43 +++++++++++++++++++++
 configure     |   18 +++++++++
 4 files changed, 179 insertions(+), 0 deletions(-)
 create mode 100644 compatfd.c
 create mode 100644 compatfd.h
Makefile.objs +1 -0
index 816194a..d73002d 100644
@@ -125,6 +125,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
+common-obj-$(CONFIG_IOTHREAD) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o
 
compatfd.c new file +117 -0

117 lines not on this page · raw message

compatfd.h new file +43 -0

43 lines not on this page · raw message

configure +18 -0
index a079a49..ae8188e 100755
@@ -1957,6 +1957,21 @@ if compile_prog "" "" ; then
   splice=yes
 fi
 
+##########################################
+# signalfd probe
+signalfd="no"
+cat > $TMPC << EOF
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <signal.h>
+int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }
+EOF
+
+if compile_prog "" "" ; then
+  signalfd=yes
+fi
+
 # check if eventfd is supported
 eventfd=no
 cat > $TMPC << EOF
@@ -2559,6 +2574,9 @@ fi
 if test "$fdt" = "yes" ; then
   echo "CONFIG_FDT=y" >> $config_host_mak
 fi
+if test "$signalfd" = "yes" ; then
+  echo "CONFIG_SIGNALFD=y" >> $config_host_mak
+fi
 if test "$need_offsetof" = "yes" ; then
   echo "CONFIG_NEED_OFFSETOF=y" >> $config_host_mak
 fi
Signature · 1 line
1.7.2.1
#4 lore raw

PATCH 4/10 iothread: use signalfd

In reply to Marcelo Tosatti

Block SIGALRM, SIGIO and consume them via signalfd.

---
 cpus.c |   74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 69 insertions(+), 5 deletions(-)
cpus.c +69 -5
index b09f5e3..3875657 100644
@@ -33,6 +33,7 @@
 #include "exec-all.h"
 
 #include "cpus.h"
+#include "compatfd.h"
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -329,14 +330,75 @@ static QemuCond qemu_work_cond;
 
 static void tcg_init_ipi(void);
 static void kvm_init_ipi(CPUState *env);
-static void unblock_io_signals(void);
+static sigset_t block_io_signals(void);
+
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
 
 int qemu_init_main_loop(void)
 {
     int ret;
+    sigset_t blocked_signals;
 
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    blocked_signals = block_io_signals();
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret)
+        return ret;
+
+    /* Note eventfd must be drained before signalfd handlers run */
     ret = qemu_event_init();
     if (ret)
         return ret;
@@ -347,7 +409,6 @@ int qemu_init_main_loop(void)
     qemu_mutex_init(&qemu_global_mutex);
     qemu_mutex_lock(&qemu_global_mutex);
 
-    unblock_io_signals();
     qemu_thread_self(&io_thread);
 
     return 0;
@@ -586,19 +647,22 @@ static void kvm_init_ipi(CPUState *env)
     }
 }
 
-static void unblock_io_signals(void)
+static sigset_t block_io_signals(void)
 {
     sigset_t set;
 
+    /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
     sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 
     sigemptyset(&set);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+    return set;
 }
 
 void qemu_mutex_lock_iothread(void)
Signature · 1 line
1.7.2.1
#5 lore raw

PATCH 5/10 Expose thread_id in info cpus

In reply to Marcelo Tosatti

commit ce6325ff1af34dbaee91c8d28e792277e43f1227

Author: Glauber Costa <[email protected]>
Date:   Wed Mar 5 17:01:10 2008 -0300

Augment info cpus

This patch exposes the thread id associated with each cpu through the already well known 'info cpus' interface.

---
 cpu-defs.h |    1 +
 cpus.c     |    5 +++++
 exec.c     |    1 +
 monitor.c  |    4 ++++
 osdep.c    |   15 +++++++++++++++
 osdep.h    |    1 +
 6 files changed, 27 insertions(+), 0 deletions(-)
cpu-defs.h +1 -0
index 8d4bf86..eaed43e 100644
@@ -197,6 +197,7 @@ typedef struct CPUWatchpoint {
     int nr_cores;  /* number of cores within this CPU package */        \
     int nr_threads;/* number of threads within this CPU */              \
     int running; /* Nonzero if cpu is currently running(usermode).  */  \
+    int thread_id;                                                      \
     /* user data */                                                     \
     void *opaque;                                                       \
                                                                         \
cpus.c +5 -0
index 3875657..429993a 100644
@@ -539,6 +539,7 @@ static void *kvm_cpu_thread_fn(void *arg)
 
     qemu_mutex_lock(&qemu_global_mutex);
     qemu_thread_self(env->thread);
+    env->thread_id = get_thread_id();
     if (kvm_enabled())
         kvm_init_vcpu(env);
 
@@ -578,6 +579,10 @@ static void *tcg_cpu_thread_fn(void *arg)
     while (!qemu_system_ready)
         qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);
 
+    for (env = first_cpu; env != NULL; env = env->next_cpu) {
+        env->thread_id = get_thread_id();
+    }
+
     while (1) {
         cpu_exec_all();
         qemu_tcg_wait_io_event();
exec.c +1 -0
index 1fbe91c..c09051d 100644
@@ -637,6 +637,7 @@ void cpu_exec_init(CPUState *env)
     env->numa_node = 0;
     QTAILQ_INIT(&env->breakpoints);
     QTAILQ_INIT(&env->watchpoints);
+    env->thread_id = get_thread_id();
     *penv = env;
 #if defined(CONFIG_USER_ONLY)
     cpu_list_unlock();
monitor.c +4 -0
index 260cc02..709d0fd 100644
@@ -849,6 +849,9 @@ static void print_cpu_iter(QObject *obj, void *opaque)
         monitor_printf(mon, " (halted)");
     }
 
+    monitor_printf(mon, " thread_id=%" PRId64 " ",
+					qdict_get_int(cpu, "thread_id"));
+
     monitor_printf(mon, "\n");
 }
 
@@ -893,6 +896,7 @@ static void do_info_cpus(Monitor *mon, QObject **ret_data)
 #elif defined(TARGET_MIPS)
         qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC));
 #endif
+        qdict_put(cpu, "thread_id", qint_from_int(env->thread_id));
 
         qlist_append(cpu_list, cpu);
     }
osdep.c +15 -0
index 2e05b21..dda0f43 100644
@@ -44,6 +44,10 @@
 extern int madvise(caddr_t, size_t, int);
 #endif
 
+#ifdef CONFIG_LINUX
+#include <sys/syscall.h>
+#endif
+
 #ifdef CONFIG_EVENTFD
 #include <sys/eventfd.h>
 #endif
@@ -200,6 +204,17 @@ int qemu_create_pidfile(const char *filename)
     return 0;
 }
 
+int get_thread_id(void)
+{
+#if defined (_WIN32)
+    return GetCurrentThreadId();
+#elif defined (__linux__)
+    return syscall(SYS_gettid);
+#else
+    return getpid();
+#endif
+}
+
 #ifdef _WIN32
 
 /* mingw32 needs ffs for compilations without optimization. */
osdep.h +1 -0
index 6716281..9b3bc2e 100644
@@ -126,6 +126,7 @@ void qemu_vfree(void *ptr);
 int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_create_pidfile(const char *filename);
+int get_thread_id(void);
 
 #ifdef _WIN32
 int ffs(int i);
Signature · 1 line
1.7.2.1
#6 lore raw

PATCH 6/10 kvm: x86: add mce support

In reply to Marcelo Tosatti

Port qemu-kvm's MCE support

commit c68b2374c9048812f488e00ffb95db66c0bc07a7

Author: Huang Ying <[email protected]>
Date:   Mon Jul 20 10:00:53 2009 +0800

Add MCE simulation support to qemu/kvm

KVM ioctls are used to initialize MCE simulation and inject MCE. The real MCE simulation is implemented in Linux kernel. The Kernel part has been merged.

---
 target-i386/helper.c  |    6 +++
 target-i386/kvm.c     |   84 +++++++++++++++++++++++++++++++++++++++++++++++++
 target-i386/kvm_x86.h |   21 ++++++++++++
 3 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 target-i386/kvm_x86.h
target-i386/helper.c +6 -0
index e134340..4b430dd 100644
@@ -27,6 +27,7 @@
 #include "exec-all.h"
 #include "qemu-common.h"
 #include "kvm.h"
+#include "kvm_x86.h"
 
 //#define DEBUG_MMU
 
@@ -1030,6 +1031,11 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
     if (bank >= bank_num || !(status & MCI_STATUS_VAL))
         return;
 
+    if (kvm_enabled()) {
+        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+        return;
+    }
+
     /*
      * if MSR_MCG_CTL is not all 1s, the uncorrected error
      * reporting is disabled
target-i386/kvm.c +84 -0

102 lines not on this page · raw message

target-i386/kvm_x86.h new file +21 -0
new file mode 100644
index 0000000..c1ebd24
@@ -0,0 +1,21 @@
+/*
+ * QEMU KVM support
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <[email protected]>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef __KVM_X86_H__
+#define __KVM_X86_H__
+
+void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc);
+
+#endif
Signature · 1 line
1.7.2.1
#7 lore raw

PATCH 7/10 Export qemu_ram_addr_from_host

In reply to Marcelo Tosatti

To be used by next patches.

---
 cpu-common.h |    3 ++-
 exec-all.h   |    2 +-
 exec.c       |   26 +++++++++++++++++---------
 3 files changed, 20 insertions(+), 11 deletions(-)
cpu-common.h +2 -1
index 0426bc8..a543b5d 100644
@@ -47,7 +47,8 @@ void qemu_ram_free(ram_addr_t addr);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
 /* This should not be used by devices.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr);
+int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
 
 int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                            CPUWriteMemoryFunc * const *mem_write,
exec-all.h +1 -1
index 3a53fe6..c457058 100644
@@ -334,7 +334,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add
     }
     p = (void *)(unsigned long)addr
         + env1->tlb_table[mmu_idx][page_index].addend;
-    return qemu_ram_addr_from_host(p);
+    return qemu_ram_addr_from_host_nofail(p);
 }
 #endif
 
exec.c +17 -9
index c09051d..9991203 100644
@@ -2086,7 +2086,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
         p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
             + tlb_entry->addend);
-        ram_addr = qemu_ram_addr_from_host(p);
+        ram_addr = qemu_ram_addr_from_host_nofail(p);
         if (!cpu_physical_memory_is_dirty(ram_addr)) {
             tlb_entry->addr_write |= TLB_NOTDIRTY;
         }
@@ -2939,23 +2939,31 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
     return NULL;
 }
 
-/* Some of the softmmu routines need to translate from a host pointer
-   (typically a TLB entry) back to a ram offset.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr)
+int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
     uint8_t *host = ptr;
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (host - block->host < block->length) {
-            return block->offset + (host - block->host);
+            *ram_addr = block->offset + (host - block->host);
+            return 0;
         }
     }
+    return -1;
+}
 
-    fprintf(stderr, "Bad ram pointer %p\n", ptr);
-    abort();
+/* Some of the softmmu routines need to translate from a host pointer
+   (typically a TLB entry) back to a ram offset.  */
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
+{
+    ram_addr_t ram_addr;
 
-    return 0;
+    if (qemu_ram_addr_from_host(ptr, &ram_addr)) {
+        fprintf(stderr, "Bad ram pointer %p\n", ptr);
+        abort();
+    }
+    return ram_addr;
 }
 
 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
@@ -3704,7 +3712,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
 {
     if (buffer != bounce.buffer) {
         if (is_write) {
-            ram_addr_t addr1 = qemu_ram_addr_from_host(buffer);
+            ram_addr_t addr1 = qemu_ram_addr_from_host_nofail(buffer);
             while (access_len) {
                 unsigned l;
                 l = TARGET_PAGE_SIZE;
Signature · 1 line
1.7.2.1
#8 lore raw

PATCH 8/10 Add RAM -> physical addr mapping in MCE simulation

In reply to Marcelo Tosatti

From: Huang Ying <[email protected]>

In QEMU-KVM, physical address != RAM address. While MCE simulation needs physical address instead of RAM address. So kvm_physical_memory_addr_from_ram() is implemented to do the conversion, and it is invoked before being filled in the IA32_MCi_ADDR MSR.

---
 kvm-all.c |   18 ++++++++++++++++++
 kvm.h     |    3 +++
 2 files changed, 21 insertions(+), 0 deletions(-)
kvm-all.c +18 -0
index 1cc696f..37b99c7 100644
@@ -137,6 +137,24 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s,
     return found;
 }
 
+int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr,
+                                      target_phys_addr_t *phys_addr)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+        KVMSlot *mem = &s->slots[i];
+
+        if (ram_addr >= mem->phys_offset &&
+            ram_addr < mem->phys_offset + mem->memory_size) {
+            *phys_addr = mem->start_addr + (ram_addr - mem->phys_offset);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
 static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
 {
     struct kvm_userspace_memory_region mem;
kvm.h +3 -0
index 50b6c01..8f5a754 100644
@@ -174,6 +174,9 @@ static inline void cpu_synchronize_post_init(CPUState *env)
     }
 }
 
+int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr,
+                                      target_phys_addr_t *phys_addr);
+
 #endif
 int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign);
 
Signature · 1 line
1.7.2.1
#9 lore raw

PATCH 9/10 MCE: Relay UCR MCE to guest

In reply to Marcelo Tosatti

Port qemu-kvm's

commit 4b62fff1101a7ad77553147717a8bd3bf79df7ef

Author: Huang Ying <[email protected]>
Date:   Mon Sep 21 10:43:25 2009 +0800

MCE: Relay UCR MCE to guest

UCR (uncorrected recovery) MCE is supported in recent Intel CPUs, where some hardware error such as some memory error can be reported without PCC (processor context corrupted). To recover from such MCE, the corresponding memory will be unmapped, and all processes accessing the memory will be killed via SIGBUS.

For KVM, if QEMU/KVM is killed, all guest processes will be killed too. So we relay SIGBUS from host OS to guest system via a UCR MCE injection. Then guest OS can isolate corresponding memory and kill necessary guest processes only. SIGBUS sent to main thread (not VCPU threads) will be broadcast to all VCPU threads as UCR MCE.

---
 cpus.c                |   82 ++++++++++++++++++++--
 kvm-stub.c            |    5 ++
 kvm.h                 |    3 +
 target-i386/cpu.h     |   20 +++++-
 target-i386/helper.c  |    2 +-
 target-i386/kvm.c     |  178 ++++++++++++++++++++++++++++++++++++++++++++++++-
 target-i386/kvm_x86.h |    3 +-
 7 files changed, 279 insertions(+), 14 deletions(-)
cpus.c +74 -8
index 429993a..62de0bc 100644
@@ -34,6 +34,10 @@
 
 #include "cpus.h"
 #include "compatfd.h"
+#ifdef CONFIG_LINUX
+#include <sys/prctl.h>
+#include <sys/signalfd.h>
+#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -41,6 +45,10 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifndef PR_MCE_KILL
+#define PR_MCE_KILL 33
+#endif
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -498,28 +506,77 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+#if defined(TARGET_I386)
+    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
+#endif
+        sigbus_reraise();
+}
+
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 {
     struct timespec ts;
     int r, e;
     siginfo_t siginfo;
     sigset_t waitset;
+    sigset_t chkset;
 
     ts.tv_sec = timeout / 1000;
     ts.tv_nsec = (timeout % 1000) * 1000000;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
+    sigaddset(&waitset, SIGBUS);
 
-    qemu_mutex_unlock(&qemu_global_mutex);
-    r = sigtimedwait(&waitset, &siginfo, &ts);
-    e = errno;
-    qemu_mutex_lock(&qemu_global_mutex);
+    do {
+        qemu_mutex_unlock(&qemu_global_mutex);
 
-    if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-        fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
-        exit(1);
-    }
+        r = sigtimedwait(&waitset, &siginfo, &ts);
+        e = errno;
+
+        qemu_mutex_lock(&qemu_global_mutex);
+
+        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
+            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+            exit(1);
+        }
+
+        switch (r) {
+        case SIGBUS:
+#ifdef TARGET_I386
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
+#endif
+                sigbus_reraise();
+            break;
+        default:
+            break;
+        }
+
+        r = sigpending(&chkset);
+        if (r == -1) {
+            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            exit(1);
+        }
+    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
 }
 
 static void qemu_kvm_wait_io_event(CPUState *env)
@@ -645,6 +702,7 @@ static void kvm_init_ipi(CPUState *env)
 
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
@@ -655,6 +713,7 @@ static void kvm_init_ipi(CPUState *env)
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
+    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -665,8 +724,15 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+    prctl(PR_MCE_KILL, 1, 1, 0, 0);
+
     return set;
 }
 
kvm-stub.c +5 -0
index d45f9fa..5384a4b 100644
@@ -141,3 +141,8 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
 {
     return -ENOSYS;
 }
+
+int kvm_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
kvm.h +3 -0
index 8f5a754..eb6fcec 100644
@@ -110,6 +110,9 @@ int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
 
target-i386/cpu.h +18 -2
index 77eeab1..85ed30f 100644
@@ -250,16 +250,32 @@
 #define PG_ERROR_RSVD_MASK 0x08
 #define PG_ERROR_I_D_MASK  0x10
 
-#define MCG_CTL_P	(1UL<<8)   /* MCG_CAP register available */
+#define MCG_CTL_P	(1ULL<<8)   /* MCG_CAP register available */
+#define MCG_SER_P	(1ULL<<24) /* MCA recovery/new status bits */
 
-#define MCE_CAP_DEF	MCG_CTL_P
+#define MCE_CAP_DEF	(MCG_CTL_P|MCG_SER_P)
 #define MCE_BANKS_DEF	10
 
+#define MCG_STATUS_RIPV	(1ULL<<0)   /* restart ip valid */
+#define MCG_STATUS_EIPV	(1ULL<<1)   /* ip points to correct instruction */
 #define MCG_STATUS_MCIP	(1ULL<<2)   /* machine check in progress */
 
 #define MCI_STATUS_VAL	(1ULL<<63)  /* valid error */
 #define MCI_STATUS_OVER	(1ULL<<62)  /* previous errors lost */
 #define MCI_STATUS_UC	(1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_EN	(1ULL<<60)  /* error enabled */
+#define MCI_STATUS_MISCV (1ULL<<59) /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58) /* addr reg. valid */
+#define MCI_STATUS_PCC	(1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S	(1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR	(1ULL<<55)  /* Action required */
+
+/* MISC register defines */
+#define MCM_ADDR_SEGOFF	0	/* segment offset */
+#define MCM_ADDR_LINEAR	1	/* linear address */
+#define MCM_ADDR_PHYS	2	/* physical address */
+#define MCM_ADDR_MEM	3	/* memory address */
+#define MCM_ADDR_GENERIC 7	/* generic */
 
 #define MSR_IA32_TSC                    0x10
 #define MSR_IA32_APICBASE               0x1b
target-i386/helper.c +1 -1
index 4b430dd..4fff4a8 100644
@@ -1032,7 +1032,7 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
         return;
 
     if (kvm_enabled()) {
-        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
         return;
     }
 
target-i386/kvm.c +176 -2

216 lines not on this page · raw message

target-i386/kvm_x86.h +2 -1
index c1ebd24..04932cf 100644
@@ -16,6 +16,7 @@
 #define __KVM_X86_H__
 
 void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-                        uint64_t mcg_status, uint64_t addr, uint64_t misc);
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc,
+                        int abort_on_error);
 
 #endif
Signature · 1 line
1.7.2.1
#10 lore raw

PATCH 9/10 MCE: Relay UCR MCE to guest (v2)

Port qemu-kvm's

commit 4b62fff1101a7ad77553147717a8bd3bf79df7ef

Author: Huang Ying <[email protected]>
Date:   Mon Sep 21 10:43:25 2009 +0800

MCE: Relay UCR MCE to guest

UCR (uncorrected recovery) MCE is supported in recent Intel CPUs, where some hardware error such as some memory error can be reported without PCC (processor context corrupted). To recover from such MCE, the corresponding memory will be unmapped, and all processes accessing the memory will be killed via SIGBUS.

For KVM, if QEMU/KVM is killed, all guest processes will be killed too. So we relay SIGBUS from host OS to guest system via a UCR MCE injection. Then guest OS can isolate corresponding memory and kill necessary guest processes only. SIGBUS sent to main thread (not VCPU threads) will be broadcast to all VCPU threads as UCR MCE.

v2: use target_phys_addr_t type for paddr.

---

  cpus.c                |   82 ++++++++++++++++++++--
  kvm-stub.c            |    5 ++
  kvm.h                 |    3 +
  target-i386/cpu.h     |   20 +++++-
  target-i386/helper.c  |    2 +-
  target-i386/kvm.c     |  178 ++++++++++++++++++++++++++++++++++++++++++++++++-
  target-i386/kvm_x86.h |    3 +-
  7 files changed, 279 insertions(+), 14 deletions(-)
cpus.c +74 -8
index 429993a..62de0bc 100644
@@ -34,6 +34,10 @@
 
 #include "cpus.h"
 #include "compatfd.h"
+#ifdef CONFIG_LINUX
+#include <sys/prctl.h>
+#include <sys/signalfd.h>
+#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -41,6 +45,10 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifndef PR_MCE_KILL
+#define PR_MCE_KILL 33
+#endif
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -498,28 +506,77 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+#if defined(TARGET_I386)
+    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
+#endif
+        sigbus_reraise();
+}
+
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 {
     struct timespec ts;
     int r, e;
     siginfo_t siginfo;
     sigset_t waitset;
+    sigset_t chkset;
 
     ts.tv_sec = timeout / 1000;
     ts.tv_nsec = (timeout % 1000) * 1000000;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
+    sigaddset(&waitset, SIGBUS);
 
-    qemu_mutex_unlock(&qemu_global_mutex);
-    r = sigtimedwait(&waitset, &siginfo, &ts);
-    e = errno;
-    qemu_mutex_lock(&qemu_global_mutex);
+    do {
+        qemu_mutex_unlock(&qemu_global_mutex);
 
-    if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-        fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
-        exit(1);
-    }
+        r = sigtimedwait(&waitset, &siginfo, &ts);
+        e = errno;
+
+        qemu_mutex_lock(&qemu_global_mutex);
+
+        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
+            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+            exit(1);
+        }
+
+        switch (r) {
+        case SIGBUS:
+#ifdef TARGET_I386
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
+#endif
+                sigbus_reraise();
+            break;
+        default:
+            break;
+        }
+
+        r = sigpending(&chkset);
+        if (r == -1) {
+            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            exit(1);
+        }
+    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
 }
 
 static void qemu_kvm_wait_io_event(CPUState *env)
@@ -645,6 +702,7 @@ static void kvm_init_ipi(CPUState *env)
 
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
@@ -655,6 +713,7 @@ static void kvm_init_ipi(CPUState *env)
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
+    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -665,8 +724,15 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+    prctl(PR_MCE_KILL, 1, 1, 0, 0);
+
     return set;
 }
 
kvm-stub.c +5 -0
index d45f9fa..5384a4b 100644
@@ -141,3 +141,8 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
 {
     return -ENOSYS;
 }
+
+int kvm_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
kvm.h +3 -0
index 8f5a754..eb6fcec 100644
@@ -110,6 +110,9 @@ int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
 
target-i386/cpu.h +18 -2
index 77eeab1..85ed30f 100644
@@ -250,16 +250,32 @@
 #define PG_ERROR_RSVD_MASK 0x08
 #define PG_ERROR_I_D_MASK  0x10
 
-#define MCG_CTL_P	(1UL<<8)   /* MCG_CAP register available */
+#define MCG_CTL_P	(1ULL<<8)   /* MCG_CAP register available */
+#define MCG_SER_P	(1ULL<<24) /* MCA recovery/new status bits */
 
-#define MCE_CAP_DEF	MCG_CTL_P
+#define MCE_CAP_DEF	(MCG_CTL_P|MCG_SER_P)
 #define MCE_BANKS_DEF	10
 
+#define MCG_STATUS_RIPV	(1ULL<<0)   /* restart ip valid */
+#define MCG_STATUS_EIPV	(1ULL<<1)   /* ip points to correct instruction */
 #define MCG_STATUS_MCIP	(1ULL<<2)   /* machine check in progress */
 
 #define MCI_STATUS_VAL	(1ULL<<63)  /* valid error */
 #define MCI_STATUS_OVER	(1ULL<<62)  /* previous errors lost */
 #define MCI_STATUS_UC	(1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_EN	(1ULL<<60)  /* error enabled */
+#define MCI_STATUS_MISCV (1ULL<<59) /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58) /* addr reg. valid */
+#define MCI_STATUS_PCC	(1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S	(1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR	(1ULL<<55)  /* Action required */
+
+/* MISC register defines */
+#define MCM_ADDR_SEGOFF	0	/* segment offset */
+#define MCM_ADDR_LINEAR	1	/* linear address */
+#define MCM_ADDR_PHYS	2	/* physical address */
+#define MCM_ADDR_MEM	3	/* memory address */
+#define MCM_ADDR_GENERIC 7	/* generic */
 
 #define MSR_IA32_TSC                    0x10
 #define MSR_IA32_APICBASE               0x1b
target-i386/helper.c +1 -1
index 4b430dd..4fff4a8 100644
@@ -1032,7 +1032,7 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
         return;
 
     if (kvm_enabled()) {
-        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
         return;
     }
 
target-i386/kvm.c +176 -2

216 lines not on this page · raw message

target-i386/kvm_x86.h +2 -1
index c1ebd24..04932cf 100644
@@ -16,6 +16,7 @@
 #define __KVM_X86_H__
 
 void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-                        uint64_t mcg_status, uint64_t addr, uint64_t misc);
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc,
+                        int abort_on_error);
 
 #endif
Signature · 6 lines
1.7.2.1

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#11 lore raw

PATCH 10/10 Add savevm/loadvm support for MCE

In reply to Marcelo Tosatti

Port qemu-kvm's

commit 1bab5d11545d8de5facf46c28630085a2f9651ae

Author: Huang Ying <[email protected]>
Date:   Wed Mar 3 16:52:46 2010 +0800

Add savevm/loadvm support for MCE

MCE registers are saved/load into/from CPUState in kvm_arch_save/load_regs. To simulate the MCG_STATUS clearing upon reset, MSR_MCG_STATUS is set to 0 for KVM_PUT_RESET_STATE.

---
 target-i386/kvm.c |   39 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 38 insertions(+), 1 deletions(-)
target-i386/kvm.c +38 -1
index 84bd400..d940175 100644
@@ -777,7 +777,7 @@ static int kvm_put_msrs(CPUState *env, int level)
         struct kvm_msr_entry entries[100];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
-    int n = 0;
+    int i, n = 0;
 
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
@@ -797,6 +797,18 @@ static int kvm_put_msrs(CPUState *env, int level)
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
     }
+#ifdef KVM_CAP_MCE
+    if (env->mcg_cap) {
+        if (level == KVM_PUT_RESET_STATE)
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+        else if (level == KVM_PUT_FULL_STATE) {
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl);
+            for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++)
+                kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
+        }
+    }
+#endif
 
     msr_data.info.nmsrs = n;
 
@@ -1004,6 +1016,15 @@ static int kvm_get_msrs(CPUState *env)
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
 
+#ifdef KVM_CAP_MCE
+    if (env->mcg_cap) {
+        msrs[n++].index = MSR_MCG_STATUS;
+        msrs[n++].index = MSR_MCG_CTL;
+        for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++)
+            msrs[n++].index = MSR_MC0_CTL + i;
+    }
+#endif
+
     msr_data.info.nmsrs = n;
     ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data);
     if (ret < 0)
@@ -1046,6 +1067,22 @@ static int kvm_get_msrs(CPUState *env)
         case MSR_KVM_WALL_CLOCK:
             env->wall_clock_msr = msrs[i].data;
             break;
+#ifdef KVM_CAP_MCE
+        case MSR_MCG_STATUS:
+            env->mcg_status = msrs[i].data;
+            break;
+        case MSR_MCG_CTL:
+            env->mcg_ctl = msrs[i].data;
+            break;
+#endif
+        default:
+#ifdef KVM_CAP_MCE
+            if (msrs[i].index >= MSR_MC0_CTL &&
+                msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
+                env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
+                break;
+            }
+#endif
         }
     }
 
Signature · 1 line
1.7.2.1
#12 lore raw
In reply to Marcelo Tosatti
Quoted 7 lines · Marcelo Tosatti

The following changes since commit 38cc9b607f85017b095793cab6c129bc9844f441:

   issue snd_pcm_start() when capturing audio (2010-10-18 00:39:06 +0400)

are available in the git repository at:
git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master

This breaks the build.

cc1: warnings being treated as errors
/home/anthony/git/qemu/target-i386/kvm.c: In function ‘kvm_on_sigbus_vcpu’:
/home/anthony/git/qemu/target-i386/kvm.c:1671: error: passing argument 3 of ‘kvm_physical_memory_addr_from_ram’ from incompatible pointer type /home/anthony/git/qemu/kvm.h:180: note: expected ‘target_phys_addr_t *’ but argument is of type ‘long unsigned int *’ /home/anthony/git/qemu/target-i386/kvm.c: In function ‘kvm_on_sigbus’:
/home/anthony/git/qemu/target-i386/kvm.c:1714: error: passing argument 3 of ‘kvm_physical_memory_addr_from_ram’ from incompatible pointer type /home/anthony/git/qemu/kvm.h:180: note: expected ‘target_phys_addr_t *’ but argument is of type ‘long unsigned int *’ make[1]: *** [kvm.o] Error 1
make: *** [subdir-i386-softmmu] Error 2

I've pushed my tree to http://repo.or.cz/w/qemu/aliguori.git qemu-kvm-20101019 but the merge is a fast-forward so you should have no trouble reproducing.

anthony@titi:~/build/qemu$ uname -a
Linux titi 2.6.32.11+drm33.2-x201 #1 SMP Sat May 22 09:58:34 PDT 2010 x86_64 GNU/Linux
anthony@titi:~/build/qemu$ gcc -v
Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4 --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-plugin --enable-objc-gc --disable-werror --with-arch-32=i486 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

Regards,

Anthony Liguori

Quoted 43 lines

Huang Ying (1):

       Add RAM ->  physical addr mapping in MCE simulation

Joerg Roedel (2):
Set cpuid definition to 0 before initializing it Add svm cpuid features

Marcelo Tosatti (7):
signalfd compatibility
iothread: use signalfd
Expose thread_id in info cpus
kvm: x86: add mce support
Export qemu_ram_addr_from_host
MCE: Relay UCR MCE to guest
Add savevm/loadvm support for MCE

  Makefile.objs         |    1 +
  compatfd.c            |  117 +++++++++++++++++++
  compatfd.h            |   43 +++++++
  configure             |   18 +++
  cpu-common.h          |    3 +-
  cpu-defs.h            |    1 +
  cpus.c                |  161 ++++++++++++++++++++++++--
  exec-all.h            |    2 +-
  exec.c                |   27 +++--
  kvm-all.c             |   18 +++
  kvm-stub.c            |    5 +
  kvm.h                 |    6 +
  monitor.c             |    4 +
  osdep.c               |   15 +++
  osdep.h               |    1 +
  target-i386/cpu.h     |   32 +++++-
  target-i386/cpuid.c   |   79 ++++++++++---
  target-i386/helper.c  |    6 +
  target-i386/kvm.c     |  300 ++++++++++++++++++++++++++++++++++++++++++++++++-
  target-i386/kvm_x86.h |   22 ++++
  20 files changed, 817 insertions(+), 44 deletions(-)

create mode 100644 compatfd.c
create mode 100644 compatfd.h
create mode 100644 target-i386/kvm_x86.h