qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code
@ 2010-02-19 18:22 Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 1/9] qemu-kvm: Drop vmport changes Jan Kiszka
                   ` (9 more replies)
  0 siblings, 10 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Spin-off from my longer series as Marcelo asked for the last patch as
the next step. I don't see any value in reordering the series, so I just
but off the lower bits.

This part mostly cleans up common KVM code that is also present
upstream. It also includes the fixed guest debug writeback, first for
upstream (patch 8 should be queued into uq/master as well), then merged
into qemu-kvm while dropping the qemu-kvm copy of the guest debugging
code.

The differences to previous postings of the full series are:
 - rebased over qemu-kvm
 - fixed guest state writeback to avoid conflicts with SET_VCPU_EVENTS,
   rather use them on modern kernels (I know Gleb will hate me for this,
   but I'm convinced it's cleaner that way)

Pull URL is

	git://git.kiszka.org/qemu-kvm.git queues/queues-kvm-merge

Jan Kiszka (9):
  qemu-kvm: Drop vmport changes
  qemu-kvm: Clean up register access API
  qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state
  qemu-kvm: Use upstream kvm_setup_guest_memory
  qemu-kvm: Use some more upstream prototypes
  qemu-kvm: Use upstream kvm_arch_get_supported_cpuid
  qemu-kvm: Use upstream kvm_pit_in_kernel
  KVM: Rework of guest debug state writing
  qemu-kvm: Use upstream guest debug code

 hw/i8254.c            |    6 +-
 hw/i8259.c            |    2 +-
 hw/ioapic.c           |    2 +-
 hw/msix.c             |    3 +-
 hw/pc.c               |    4 +-
 hw/pcspk.c            |    4 +-
 hw/piix_pci.c         |    2 +-
 hw/vmport.c           |   13 +--
 kvm-all.c             |   24 ++---
 kvm.h                 |   11 +--
 qemu-kvm-x86.c        |  319 ++++++-------------------------------------------
 qemu-kvm.c            |  110 ++----------------
 qemu-kvm.h            |  139 +--------------------
 target-i386/kvm.c     |   43 ++++++-
 target-ia64/machine.c |    4 +-
 vl.c                  |    3 +-
 16 files changed, 114 insertions(+), 575 deletions(-)

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

* [Qemu-devel] [PATCH 1/9] qemu-kvm: Drop vmport changes
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 2/9] qemu-kvm: Clean up register access API Jan Kiszka
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Upstream has proper support now. Drop the old half-broken approach and
all surrounding diffs.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/vmport.c |   13 +------------
 1 files changed, 1 insertions(+), 12 deletions(-)

diff --git a/hw/vmport.c b/hw/vmport.c
index e9db6de..6c9d7c9 100644
--- a/hw/vmport.c
+++ b/hw/vmport.c
@@ -21,12 +21,10 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
-
 #include "hw.h"
 #include "isa.h"
 #include "pc.h"
 #include "sysemu.h"
-#include "qemu-kvm.h"
 #include "kvm.h"
 
 //#define VMPORT_DEBUG
@@ -60,10 +58,6 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
     CPUState *env = cpu_single_env;
     unsigned char command;
     uint32_t eax;
-    uint32_t ret;
-
-    if (kvm_enabled())
-	kvm_save_registers(env);
 
     cpu_synchronize_state(env);
 
@@ -82,12 +76,7 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
         return eax;
     }
 
-    ret = s->func[command](s->opaque[command], addr);
-
-    if (kvm_enabled())
-	kvm_load_registers(env);
-
-    return ret;
+    return s->func[command](s->opaque[command], addr);
 }
 
 static void vmport_ioport_write(void *opaque, uint32_t addr, uint32_t val)
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 2/9] qemu-kvm: Clean up register access API
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 1/9] qemu-kvm: Drop vmport changes Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-21  9:25   ` [Qemu-devel] " Avi Kivity
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 3/9] qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state Jan Kiszka
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

qemu-kvm's functions for accessing the VCPU registers are
kvm_arch_load/save_regs. Use them directly instead of going through
various wrappers. Specifically, we do not need on_vcpu wrapping as all
users either already run in the related thread or call while the vm is
stopped. This is now also validated during runtime via asserts.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 qemu-kvm-x86.c        |    4 ++++
 qemu-kvm.c            |   46 ++++++++--------------------------------------
 qemu-kvm.h            |   14 +++-----------
 target-ia64/machine.c |    4 ++--
 4 files changed, 17 insertions(+), 51 deletions(-)

diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 7f820a4..4cb1cb3 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -911,6 +911,8 @@ void kvm_arch_load_regs(CPUState *env)
     struct kvm_msr_entry msrs[100];
     int rc, n, i;
 
+    assert(kvm_cpu_is_stopped(env) || env->thread_id == kvm_get_thread_id());
+
     regs.rax = env->regs[R_EAX];
     regs.rbx = env->regs[R_EBX];
     regs.rcx = env->regs[R_ECX];
@@ -1072,6 +1074,8 @@ void kvm_arch_save_regs(CPUState *env)
     uint32_t hflags;
     uint32_t i, n, rc, bit;
 
+    assert(kvm_cpu_is_stopped(env) || env->thread_id == kvm_get_thread_id());
+
     kvm_get_regs(env, &regs);
 
     env->regs[R_EAX] = regs.rax;
diff --git a/qemu-kvm.c b/qemu-kvm.c
index b534d4e..555d959 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -871,7 +871,7 @@ int pre_kvm_run(kvm_context_t kvm, CPUState *env)
     kvm_arch_pre_run(env, env->kvm_run);
 
     if (env->kvm_vcpu_dirty) {
-        kvm_arch_put_registers(env);
+        kvm_arch_load_regs(env);
         env->kvm_vcpu_dirty = 0;
     }
 
@@ -1438,7 +1438,7 @@ int kvm_irqfd(kvm_context_t kvm, int gsi, int flags)
 }
 
 #endif                          /* KVM_CAP_IRQFD */
-static inline unsigned long kvm_get_thread_id(void)
+unsigned long kvm_get_thread_id(void)
 {
     return syscall(SYS_gettid);
 }
@@ -1541,16 +1541,12 @@ static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
         qemu_cond_wait(&qemu_work_cond);
 }
 
-void kvm_arch_get_registers(CPUState *env)
-{
-	kvm_arch_save_regs(env);
-}
-
 static void do_kvm_cpu_synchronize_state(void *_env)
 {
     CPUState *env = _env;
+
     if (!env->kvm_vcpu_dirty) {
-        kvm_arch_get_registers(env);
+        kvm_arch_save_regs(env);
         env->kvm_vcpu_dirty = 1;
     }
 }
@@ -1593,32 +1589,6 @@ void kvm_update_interrupt_request(CPUState *env)
     }
 }
 
-static void kvm_do_load_registers(void *_env)
-{
-    CPUState *env = _env;
-
-    kvm_arch_load_regs(env);
-}
-
-void kvm_load_registers(CPUState *env)
-{
-    if (kvm_enabled() && qemu_system_ready)
-        on_vcpu(env, kvm_do_load_registers, env);
-}
-
-static void kvm_do_save_registers(void *_env)
-{
-    CPUState *env = _env;
-
-    kvm_arch_save_regs(env);
-}
-
-void kvm_save_registers(CPUState *env)
-{
-    if (kvm_enabled())
-        on_vcpu(env, kvm_do_save_registers, env);
-}
-
 static void kvm_do_load_mpstate(void *_env)
 {
     CPUState *env = _env;
@@ -1662,7 +1632,7 @@ int kvm_cpu_exec(CPUState *env)
     return 0;
 }
 
-static int is_cpu_stopped(CPUState *env)
+int kvm_cpu_is_stopped(CPUState *env)
 {
     return !vm_running || env->stopped;
 }
@@ -1889,7 +1859,7 @@ static void process_irqchip_events(CPUState *env)
 static int kvm_main_loop_cpu(CPUState *env)
 {
     while (1) {
-        int run_cpu = !is_cpu_stopped(env);
+        int run_cpu = !kvm_cpu_is_stopped(env);
         if (run_cpu && !kvm_irqchip_in_kernel()) {
             process_irqchip_events(env);
             run_cpu = !env->halted;
@@ -2372,8 +2342,8 @@ static void kvm_invoke_set_guest_debug(void *data)
     struct kvm_set_guest_debug_data *dbg_data = data;
 
     if (cpu_single_env->kvm_vcpu_dirty) {
-        kvm_arch_put_registers(cpu_single_env);
-        cpu_single_env->kvm_vcpu_dirty = 1;
+        kvm_arch_save_regs(cpu_single_env);
+        cpu_single_env->kvm_vcpu_dirty = 0;
     }
     dbg_data->err =
         kvm_set_guest_debug(cpu_single_env,
diff --git a/qemu-kvm.h b/qemu-kvm.h
index c1675d4..9c132da 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -902,8 +902,6 @@ int kvm_main_loop(void);
 int kvm_init_ap(void);
 #ifndef QEMU_KVM_NO_CPU
 int kvm_vcpu_inited(CPUState *env);
-void kvm_load_registers(CPUState *env);
-void kvm_save_registers(CPUState *env);
 void kvm_load_mpstate(CPUState *env);
 void kvm_save_mpstate(CPUState *env);
 int kvm_cpu_exec(CPUState *env);
@@ -1069,8 +1067,6 @@ void kvm_load_tsc(CPUState *env);
 #ifdef TARGET_I386
 #define qemu_kvm_has_pit_state2() (0)
 #endif
-#define kvm_load_registers(env) do {} while(0)
-#define kvm_save_registers(env) do {} while(0)
 #define kvm_save_mpstate(env)   do {} while(0)
 #define qemu_kvm_cpu_stop(env) do {} while(0)
 static inline void kvm_init_vcpu(CPUState *env)
@@ -1099,13 +1095,6 @@ static inline int kvm_sync_vcpus(void)
 }
 
 #ifndef QEMU_KVM_NO_CPU
-void kvm_arch_get_registers(CPUState *env);
-
-static inline void kvm_arch_put_registers(CPUState *env)
-{
-    kvm_load_registers(env);
-}
-
 void kvm_cpu_synchronize_state(CPUState *env);
 
 static inline void cpu_synchronize_state(CPUState *env)
@@ -1168,6 +1157,9 @@ int kvm_check_extension(KVMState *s, unsigned int ext);
 
 int kvm_tpr_enable_vapic(CPUState *env);
 
+unsigned long kvm_get_thread_id(void);
+int kvm_cpu_is_stopped(CPUState *env);
+
 #endif
 
 #endif
diff --git a/target-ia64/machine.c b/target-ia64/machine.c
index 70ef379..7d29575 100644
--- a/target-ia64/machine.c
+++ b/target-ia64/machine.c
@@ -9,7 +9,7 @@ void cpu_save(QEMUFile *f, void *opaque)
     CPUState *env = opaque;
 
     if (kvm_enabled()) {
-        kvm_save_registers(env);
+        kvm_arch_save_regs(env);
         kvm_arch_save_mpstate(env);
     }
 }
@@ -19,7 +19,7 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
     CPUState *env = opaque;
 
     if (kvm_enabled()) {
-        kvm_load_registers(env);
+        kvm_arch_load_regs(env);
         kvm_arch_load_mpstate(env);
     }
     return 0;
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 3/9] qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 1/9] qemu-kvm: Drop vmport changes Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 2/9] qemu-kvm: Clean up register access API Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 4/9] qemu-kvm: Use upstream kvm_setup_guest_memory Jan Kiszka
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

They are identical, no need for private copies. This requires replacing
qemu-kvm.h includes with kvm.h, a good thing anyway, and reveals that
there is no need for QEMU_KVM_NO_CPU protection.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/i8254.c    |    2 +-
 hw/i8259.c    |    2 +-
 hw/ioapic.c   |    2 +-
 hw/msix.c     |    3 +--
 hw/pc.c       |    2 +-
 hw/piix_pci.c |    2 +-
 kvm.h         |    7 +++----
 qemu-kvm.h    |   41 -----------------------------------------
 vl.c          |    3 ++-
 9 files changed, 11 insertions(+), 53 deletions(-)

diff --git a/hw/i8254.c b/hw/i8254.c
index c4f8d2e..db9e94a 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -25,7 +25,7 @@
 #include "pc.h"
 #include "isa.h"
 #include "qemu-timer.h"
-#include "qemu-kvm.h"
+#include "kvm.h"
 #include "i8254.h"
 
 //#define DEBUG_PIT
diff --git a/hw/i8259.c b/hw/i8259.c
index 7a484c0..b64c6fb 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -27,7 +27,7 @@
 #include "monitor.h"
 #include "qemu-timer.h"
 
-#include "qemu-kvm.h"
+#include "kvm.h"
 
 /* debug PIC */
 //#define DEBUG_PIC
diff --git a/hw/ioapic.c b/hw/ioapic.c
index a66325d..0adb0ac 100644
--- a/hw/ioapic.c
+++ b/hw/ioapic.c
@@ -26,7 +26,7 @@
 #include "qemu-timer.h"
 #include "host-utils.h"
 
-#include "qemu-kvm.h"
+#include "kvm.h"
 
 //#define DEBUG_IOAPIC
 
diff --git a/hw/msix.c b/hw/msix.c
index 87f125b..faee0b2 100644
--- a/hw/msix.c
+++ b/hw/msix.c
@@ -14,8 +14,7 @@
 #include "hw.h"
 #include "msix.h"
 #include "pci.h"
-#define QEMU_KVM_NO_CPU
-#include "qemu-kvm.h"
+#include "kvm.h"
 
 /* Declaration from linux/pci_regs.h */
 #define  PCI_CAP_ID_MSIX 0x11 /* MSI-X */
diff --git a/hw/pc.c b/hw/pc.c
index 6c98797..55df58d 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -47,7 +47,7 @@
 #include "multiboot.h"
 #include "device-assignment.h"
 
-#include "qemu-kvm.h"
+#include "kvm.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 155587b..170f858 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -28,7 +28,7 @@
 #include "pci_host.h"
 #include "isa.h"
 #include "sysbus.h"
-#include "qemu-kvm.h"
+#include "kvm.h"
 
 /*
  * I440FX chipset data sheet.
diff --git a/kvm.h b/kvm.h
index f6e4087..f97efa3 100644
--- a/kvm.h
+++ b/kvm.h
@@ -18,8 +18,6 @@
 #include "qemu-queue.h"
 #include "qemu-kvm.h"
 
-#ifdef KVM_UPSTREAM
-
 #ifdef CONFIG_KVM
 extern int kvm_allowed;
 
@@ -28,6 +26,7 @@ extern int kvm_allowed;
 #define kvm_enabled() (0)
 #endif
 
+#ifdef KVM_UPSTREAM
 struct kvm_run;
 
 /* external API */
@@ -133,6 +132,8 @@ int kvm_check_extension(KVMState *s, unsigned int extension);
 
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                                       int reg);
+#endif
+
 void kvm_cpu_synchronize_state(CPUState *env);
 
 /* generic hooks - to be moved/refactored once there are more users */
@@ -145,5 +146,3 @@ static inline void cpu_synchronize_state(CPUState *env)
 }
 
 #endif
-
-#endif
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 9c132da..069d2c6 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -8,9 +8,7 @@
 #ifndef THE_ORIGINAL_AND_TRUE_QEMU_KVM_H
 #define THE_ORIGINAL_AND_TRUE_QEMU_KVM_H
 
-#ifndef QEMU_KVM_NO_CPU
 #include "cpu.h"
-#endif
 
 #include <signal.h>
 #include <stdlib.h>
@@ -94,8 +92,6 @@ void kvm_show_code(CPUState *env);
 
 int handle_halt(CPUState *env);
 
-#ifndef QEMU_KVM_NO_CPU
-
 int handle_shutdown(kvm_context_t kvm, CPUState *env);
 void post_kvm_run(kvm_context_t kvm, CPUState *env);
 int pre_kvm_run(kvm_context_t kvm, CPUState *env);
@@ -113,8 +109,6 @@ struct kvm_x86_mce;
 int kvm_set_mce(CPUState *env, struct kvm_x86_mce *mce);
 #endif
 
-#endif
-
 /*!
  * \brief Create new KVM context
  *
@@ -880,8 +874,6 @@ static inline int kvm_init(int smp_cpus)
     return 0;
 }
 
-#ifndef QEMU_KVM_NO_CPU
-
 static inline void kvm_inject_x86_mce(CPUState *cenv, int bank,
                                       uint64_t status, uint64_t mcg_status,
                                       uint64_t addr, uint64_t misc,
@@ -891,16 +883,11 @@ static inline void kvm_inject_x86_mce(CPUState *cenv, int bank,
         abort();
 }
 
-#endif
-
-extern int kvm_allowed;
-
 #endif                          /* !CONFIG_KVM */
 
 
 int kvm_main_loop(void);
 int kvm_init_ap(void);
-#ifndef QEMU_KVM_NO_CPU
 int kvm_vcpu_inited(CPUState *env);
 void kvm_load_mpstate(CPUState *env);
 void kvm_save_mpstate(CPUState *env);
@@ -914,7 +901,6 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
 void kvm_apic_init(CPUState *env);
 /* called from vcpu initialization */
 void qemu_kvm_load_lapic(CPUState *env);
-#endif
 
 void kvm_hpet_enable_kpit(void);
 void kvm_hpet_disable_kpit(void);
@@ -923,13 +909,11 @@ int kvm_set_irq(int irq, int level, int *status);
 int kvm_physical_memory_set_dirty_tracking(int enable);
 int kvm_update_dirty_pages_log(void);
 
-#ifndef QEMU_KVM_NO_CPU
 void qemu_kvm_call_with_env(void (*func)(void *), void *data, CPUState *env);
 void qemu_kvm_cpuid_on_env(CPUState *env);
 void kvm_inject_interrupt(CPUState *env, int mask);
 void kvm_update_after_sipi(CPUState *env);
 void kvm_update_interrupt_request(CPUState *env);
-#endif
 void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
                       ram_addr_t phys_offset);
 void *kvm_cpu_create_phys_mem(target_phys_addr_t start_addr, unsigned long size,
@@ -946,7 +930,6 @@ int kvm_qemu_destroy_memory_alias(uint64_t phys_start);
 
 int kvm_arch_qemu_create_context(void);
 
-#ifndef QEMU_KVM_NO_CPU
 void kvm_arch_save_regs(CPUState *env);
 void kvm_arch_load_regs(CPUState *env);
 void kvm_arch_load_mpstate(CPUState *env);
@@ -988,19 +971,15 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr, target_ulong len,
 void kvm_arch_remove_all_hw_breakpoints(void);
 void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
 
-#endif
-
 void qemu_kvm_aio_wait_start(void);
 void qemu_kvm_aio_wait(void);
 void qemu_kvm_aio_wait_end(void);
 
 void qemu_kvm_notify_work(void);
 
-#ifndef QEMU_KVM_NO_CPU
 void kvm_tpr_opt_setup(void);
 void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
 void kvm_tpr_vcpu_start(CPUState *env);
-#endif
 
 int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf);
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
@@ -1022,14 +1001,11 @@ void kvm_arch_do_ioperm(void *_data);
 #endif
 
 #define ALIGN(x, y)  (((x)+(y)-1) & ~((y)-1))
-#ifndef QEMU_KVM_NO_CPU
 #define BITMAP_SIZE(m) (ALIGN(((m)>>TARGET_PAGE_BITS), HOST_LONG_BITS) / 8)
-#endif
 
 #ifdef CONFIG_KVM
 #include "qemu-queue.h"
 
-extern int kvm_allowed;
 extern int kvm_irqchip;
 extern int kvm_pit;
 extern int kvm_pit_reinject;
@@ -1049,7 +1025,6 @@ int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip,
                       int is_write);
 int kvm_has_sync_mmu(void);
 
-#define kvm_enabled() (kvm_allowed)
 #define qemu_kvm_pit_in_kernel() kvm_pit_in_kernel(kvm_context)
 #define qemu_kvm_has_gsi_routing() kvm_has_gsi_routing(kvm_context)
 #ifdef TARGET_I386
@@ -1059,11 +1034,9 @@ void kvm_init_vcpu(CPUState *env);
 void kvm_load_tsc(CPUState *env);
 #else
 #define kvm_has_sync_mmu() (0)
-#define kvm_enabled() (0)
 #define kvm_nested 0
 #define qemu_kvm_pit_in_kernel() (0)
 #define qemu_kvm_has_gsi_routing() (0)
-#ifndef QEMU_KVM_NO_CPU
 #ifdef TARGET_I386
 #define qemu_kvm_has_pit_state2() (0)
 #endif
@@ -1077,7 +1050,6 @@ static inline void kvm_load_tsc(CPUState *env)
 {
 }
 #endif
-#endif
 
 void kvm_mutex_unlock(void);
 void kvm_mutex_lock(void);
@@ -1094,22 +1066,9 @@ static inline int kvm_sync_vcpus(void)
     return 0;
 }
 
-#ifndef QEMU_KVM_NO_CPU
-void kvm_cpu_synchronize_state(CPUState *env);
-
-static inline void cpu_synchronize_state(CPUState *env)
-{
-    if (kvm_enabled()) {
-        kvm_cpu_synchronize_state(env);
-    }
-}
-
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                                       int reg);
 
-
-#endif
-
 static inline int kvm_set_migration_log(int enable)
 {
     return kvm_physical_memory_set_dirty_tracking(enable);
diff --git a/vl.c b/vl.c
index 79c33b4..f7f388f 100644
--- a/vl.c
+++ b/vl.c
@@ -157,7 +157,6 @@ int main(int argc, char **argv)
 #include "qemu-option.h"
 #include "qemu-config.h"
 #include "qemu-objects.h"
-#include "qemu-kvm.h"
 #include "hw/device-assignment.h"
 
 #include "disas.h"
@@ -5825,8 +5824,10 @@ int main(int argc, char **argv, char **envp)
             fprintf(stderr, "failed to initialize KVM\n");
             exit(1);
 #endif
+#ifdef CONFIG_KVM
             fprintf(stderr, "Could not initialize KVM, will disable KVM support\n");
             kvm_allowed = 0;
+#endif
         }
     }
 
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 4/9] qemu-kvm: Use upstream kvm_setup_guest_memory
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (2 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 3/9] qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 5/9] qemu-kvm: Use some more upstream prototypes Jan Kiszka
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Nothing missing in upstream kvm_setup_guest_memory, it is even more
careful about error handling.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c  |    3 ---
 kvm.h      |    3 +--
 qemu-kvm.c |   15 ---------------
 qemu-kvm.h |    1 -
 4 files changed, 1 insertions(+), 21 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 9f1808f..b9c1553 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -932,7 +932,6 @@ int kvm_has_vcpu_events(void)
     return kvm_state->vcpu_events;
 }
 
-#ifdef KVM_UPSTREAM
 void kvm_setup_guest_memory(void *start, size_t size)
 {
     if (!kvm_has_sync_mmu()) {
@@ -951,8 +950,6 @@ void kvm_setup_guest_memory(void *start, size_t size)
     }
 }
 
-#endif /* KVM_UPSTREAM */
-
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 
 #ifdef KVM_UPSTREAM
diff --git a/kvm.h b/kvm.h
index f97efa3..724914d 100644
--- a/kvm.h
+++ b/kvm.h
@@ -48,10 +48,9 @@ int kvm_get_vcpu_events(CPUState *env);
 
 void kvm_cpu_register_phys_memory_client(void);
 
-#ifdef KVM_UPSTREAM
-
 void kvm_setup_guest_memory(void *start, size_t size);
 
+#ifdef KVM_UPSTREAM
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 555d959..17a8080 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -2315,21 +2315,6 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
     return;
 }
 
-int kvm_setup_guest_memory(void *area, unsigned long size)
-{
-    int ret = 0;
-
-#ifdef MADV_DONTFORK
-    if (kvm_enabled() && !kvm_has_sync_mmu())
-        ret = madvise(area, size, MADV_DONTFORK);
-#endif
-
-    if (ret)
-        perror("madvise");
-
-    return ret;
-}
-
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 
 struct kvm_set_guest_debug_data {
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 069d2c6..f9c797f 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -923,7 +923,6 @@ void kvm_cpu_destroy_phys_mem(target_phys_addr_t start_addr,
                               unsigned long size);
 void kvm_qemu_log_memory(target_phys_addr_t start, target_phys_addr_t size,
                          int log);
-int kvm_setup_guest_memory(void *area, unsigned long size);
 int kvm_qemu_create_memory_alias(uint64_t phys_start, uint64_t len,
                                  uint64_t target_phys);
 int kvm_qemu_destroy_memory_alias(uint64_t phys_start);
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 5/9] qemu-kvm: Use some more upstream prototypes
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (3 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 4/9] qemu-kvm: Use upstream kvm_setup_guest_memory Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 6/9] qemu-kvm: Use upstream kvm_arch_get_supported_cpuid Jan Kiszka
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Drop our private typedef of KVMState and use more identical upstream
prototypes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm.h      |    8 +++++---
 qemu-kvm.c |    4 +++-
 qemu-kvm.h |   28 +++-------------------------
 3 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/kvm.h b/kvm.h
index 724914d..b78e469 100644
--- a/kvm.h
+++ b/kvm.h
@@ -32,6 +32,7 @@ struct kvm_run;
 /* external API */
 
 int kvm_init(int smp_cpus);
+#endif /* KVM_UPSTREAM */
 
 int kvm_init_vcpu(CPUState *env);
 
@@ -41,7 +42,6 @@ int kvm_log_start(target_phys_addr_t phys_addr, ram_addr_t size);
 int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);
 
 int kvm_has_sync_mmu(void);
-#endif /* KVM_UPSTREAM */
 int kvm_has_vcpu_events(void);
 int kvm_put_vcpu_events(CPUState *env);
 int kvm_get_vcpu_events(CPUState *env);
@@ -50,11 +50,11 @@ void kvm_cpu_register_phys_memory_client(void);
 
 void kvm_setup_guest_memory(void *start, size_t size);
 
-#ifdef KVM_UPSTREAM
 int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
+#ifdef KVM_UPSTREAM
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
@@ -64,6 +64,7 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
 
 int kvm_pit_in_kernel(void);
 int kvm_irqchip_in_kernel(void);
+#endif /* KVM_UPSTREAM */
 
 /* internal API */
 
@@ -92,7 +93,6 @@ int kvm_arch_init(KVMState *s, int smp_cpus);
 
 int kvm_arch_init_vcpu(CPUState *env);
 
-#endif
 void kvm_arch_reset_vcpu(CPUState *env);
 #ifdef KVM_UPSTREAM
 
@@ -126,9 +126,11 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr,
 void kvm_arch_remove_all_hw_breakpoints(void);
 
 void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
+#endif
 
 int kvm_check_extension(KVMState *s, unsigned int extension);
 
+#ifdef KVM_UPSTREAM
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                                       int reg);
 #endif
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 17a8080..5c4f6e6 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1919,12 +1919,14 @@ static void *ap_main_loop(void *_env)
     return NULL;
 }
 
-void kvm_init_vcpu(CPUState *env)
+int kvm_init_vcpu(CPUState *env)
 {
     pthread_create(&env->kvm_cpu_state.thread, NULL, ap_main_loop, env);
 
     while (env->created == 0)
         qemu_cond_wait(&qemu_vcpu_cond);
+
+    return 0;
 }
 
 int kvm_vcpu_inited(CPUState *env)
diff --git a/qemu-kvm.h b/qemu-kvm.h
index f9c797f..1266a3f 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -891,7 +891,6 @@ int kvm_init_ap(void);
 int kvm_vcpu_inited(CPUState *env);
 void kvm_load_mpstate(CPUState *env);
 void kvm_save_mpstate(CPUState *env);
-int kvm_cpu_exec(CPUState *env);
 int kvm_insert_breakpoint(CPUState * current_env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUState * current_env, target_ulong addr,
@@ -933,9 +932,6 @@ void kvm_arch_save_regs(CPUState *env);
 void kvm_arch_load_regs(CPUState *env);
 void kvm_arch_load_mpstate(CPUState *env);
 void kvm_arch_save_mpstate(CPUState *env);
-int kvm_arch_init_vcpu(CPUState *cenv);
-int kvm_arch_pre_run(CPUState *env, struct kvm_run *run);
-int kvm_arch_post_run(CPUState *env, struct kvm_run *run);
 int kvm_arch_has_work(CPUState *env);
 void kvm_arch_process_irqchip_events(CPUState *env);
 int kvm_arch_try_push_interrupts(void *opaque);
@@ -981,9 +977,6 @@ void kvm_tpr_access_report(CPUState *env, uint64_t rip, int is_write);
 void kvm_tpr_vcpu_start(CPUState *env);
 
 int qemu_kvm_get_dirty_pages(unsigned long phys_addr, void *buf);
-int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
-int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
-void kvm_flush_coalesced_mmio_buffer(void);
 
 int kvm_arch_init_irq_routing(void);
 
@@ -1022,17 +1015,14 @@ void qemu_kvm_cpu_stop(CPUState *env);
 int kvm_arch_halt(CPUState *env);
 int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip,
                       int is_write);
-int kvm_has_sync_mmu(void);
 
 #define qemu_kvm_pit_in_kernel() kvm_pit_in_kernel(kvm_context)
 #define qemu_kvm_has_gsi_routing() kvm_has_gsi_routing(kvm_context)
 #ifdef TARGET_I386
 #define qemu_kvm_has_pit_state2() kvm_has_pit_state2(kvm_context)
 #endif
-void kvm_init_vcpu(CPUState *env);
 void kvm_load_tsc(CPUState *env);
 #else
-#define kvm_has_sync_mmu() (0)
 #define kvm_nested 0
 #define qemu_kvm_pit_in_kernel() (0)
 #define qemu_kvm_has_gsi_routing() (0)
@@ -1041,10 +1031,6 @@ void kvm_load_tsc(CPUState *env);
 #endif
 #define kvm_save_mpstate(env)   do {} while(0)
 #define qemu_kvm_cpu_stop(env) do {} while(0)
-static inline void kvm_init_vcpu(CPUState *env)
-{
-}
-
 static inline void kvm_load_tsc(CPUState *env)
 {
 }
@@ -1056,9 +1042,6 @@ void kvm_mutex_lock(void);
 int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
                                    target_phys_addr_t end_addr);
 
-int kvm_log_start(target_phys_addr_t phys_addr, target_phys_addr_t len);
-int kvm_log_stop(target_phys_addr_t phys_addr, target_phys_addr_t len);
-
 
 static inline int kvm_sync_vcpus(void)
 {
@@ -1087,7 +1070,7 @@ typedef struct KVMSlot {
 
 typedef struct kvm_dirty_log KVMDirtyLog;
 
-typedef struct KVMState {
+struct KVMState {
     KVMSlot slots[32];
     int fd;
     int vmfd;
@@ -1104,14 +1087,9 @@ typedef struct KVMState {
     int irqchip_in_kernel;
 
     struct kvm_context kvm_context;
-} KVMState;
-
-extern KVMState *kvm_state;
+};
 
-int kvm_ioctl(KVMState *s, int type, ...);
-int kvm_vm_ioctl(KVMState *s, int type, ...);
-int kvm_vcpu_ioctl(CPUState *env, int type, ...);
-int kvm_check_extension(KVMState *s, unsigned int ext);
+extern struct KVMState *kvm_state;
 
 int kvm_tpr_enable_vapic(CPUState *env);
 
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 6/9] qemu-kvm: Use upstream kvm_arch_get_supported_cpuid
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (4 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 5/9] qemu-kvm: Use some more upstream prototypes Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 7/9] qemu-kvm: Use upstream kvm_pit_in_kernel Jan Kiszka
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

It is idential to our version now, so drop the copy.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm.h             |    3 -
 qemu-kvm-x86.c    |  106 -----------------------------------------------------
 qemu-kvm.h        |    5 --
 target-i386/kvm.c |    4 +-
 4 files changed, 2 insertions(+), 116 deletions(-)

diff --git a/kvm.h b/kvm.h
index b78e469..7f32f95 100644
--- a/kvm.h
+++ b/kvm.h
@@ -130,11 +130,8 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
 
 int kvm_check_extension(KVMState *s, unsigned int extension);
 
-#ifdef KVM_UPSTREAM
 uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
                                       int reg);
-#endif
-
 void kvm_cpu_synchronize_state(CPUState *env);
 
 /* generic hooks - to be moved/refactored once there are more users */
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 4cb1cb3..a7bf446 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -627,106 +627,6 @@ int kvm_disable_tpr_access_reporting(CPUState *env)
 
 #endif
 
-#ifdef KVM_CAP_EXT_CPUID
-
-static struct kvm_cpuid2 *try_get_cpuid(kvm_context_t kvm, int max)
-{
-	struct kvm_cpuid2 *cpuid;
-	int r, size;
-
-	size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
-	cpuid = qemu_malloc(size);
-	cpuid->nent = max;
-	r = kvm_ioctl(kvm_state, KVM_GET_SUPPORTED_CPUID, cpuid);
-	if (r == 0 && cpuid->nent >= max)
-		r = -E2BIG;
-	if (r < 0) {
-		if (r == -E2BIG) {
-			free(cpuid);
-			return NULL;
-		} else {
-			fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n",
-				strerror(-r));
-			exit(1);
-		}
-	}
-	return cpuid;
-}
-
-#define R_EAX 0
-#define R_ECX 1
-#define R_EDX 2
-#define R_EBX 3
-#define R_ESP 4
-#define R_EBP 5
-#define R_ESI 6
-#define R_EDI 7
-
-uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg)
-{
-	struct kvm_cpuid2 *cpuid;
-	int i, max;
-	uint32_t ret = 0;
-	uint32_t cpuid_1_edx;
-
-	if (!kvm_check_extension(kvm_state, KVM_CAP_EXT_CPUID)) {
-		return -1U;
-	}
-
-	max = 1;
-	while ((cpuid = try_get_cpuid(kvm, max)) == NULL) {
-		max *= 2;
-	}
-
-	for (i = 0; i < cpuid->nent; ++i) {
-		if (cpuid->entries[i].function == function) {
-			switch (reg) {
-			case R_EAX:
-				ret = cpuid->entries[i].eax;
-				break;
-			case R_EBX:
-				ret = cpuid->entries[i].ebx;
-				break;
-			case R_ECX:
-				ret = cpuid->entries[i].ecx;
-				break;
-			case R_EDX:
-				ret = cpuid->entries[i].edx;
-                                if (function == 1) {
-                                    /* kvm misreports the following features
-                                     */
-                                    ret |= 1 << 12; /* MTRR */
-                                    ret |= 1 << 16; /* PAT */
-                                    ret |= 1 << 7;  /* MCE */
-                                    ret |= 1 << 14; /* MCA */
-                                }
-
-				/* On Intel, kvm returns cpuid according to
-				 * the Intel spec, so add missing bits
-				 * according to the AMD spec:
-				 */
-				if (function == 0x80000001) {
-					cpuid_1_edx = kvm_get_supported_cpuid(kvm, 1, R_EDX);
-					ret |= cpuid_1_edx & 0xdfeff7ff;
-				}
-				break;
-			}
-		}
-	}
-
-	free(cpuid);
-
-	return ret;
-}
-
-#else
-
-uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg)
-{
-	return -1U;
-}
-
-#endif
 int kvm_qemu_create_memory_alias(uint64_t phys_start,
                                  uint64_t len,
                                  uint64_t target_phys)
@@ -1690,12 +1590,6 @@ int kvm_arch_init_irq_routing(void)
     return 0;
 }
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
-                                      int reg)
-{
-    return kvm_get_supported_cpuid(kvm_context, function, reg);
-}
-
 void kvm_arch_process_irqchip_events(CPUState *env)
 {
     if (env->interrupt_request & CPU_INTERRUPT_INIT) {
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 1266a3f..967162c 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -859,8 +859,6 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm,
                               struct kvm_assigned_msix_entry *entry);
 #endif
 
-uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg);
-
 #else                           /* !CONFIG_KVM */
 
 typedef struct kvm_context *kvm_context_t;
@@ -1048,9 +1046,6 @@ static inline int kvm_sync_vcpus(void)
     return 0;
 }
 
-uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function,
-                                      int reg);
-
 static inline int kvm_set_migration_log(int enable)
 {
     return kvm_physical_memory_set_dirty_tracking(enable);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9fb96b5..8743f32 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -25,8 +25,6 @@
 #include "gdbstub.h"
 #include "host-utils.h"
 
-#ifdef KVM_UPSTREAM
-
 #ifdef CONFIG_KVM_PARA
 #include <linux/kvm_para.h>
 #endif
@@ -133,6 +131,8 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg)
 
 #endif
 
+#ifdef KVM_UPSTREAM
+
 static void kvm_trim_features(uint32_t *features, uint32_t supported)
 {
     int i;
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 7/9] qemu-kvm: Use upstream kvm_pit_in_kernel
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (5 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 6/9] qemu-kvm: Use upstream kvm_arch_get_supported_cpuid Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 8/9] KVM: Rework of guest debug state writing Jan Kiszka
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Drop private version in favor of recently added upstream service and
track it state directly in KVMState.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/i8254.c     |    4 ++--
 hw/pc.c        |    2 +-
 hw/pcspk.c     |    4 ++--
 kvm-all.c      |    2 +-
 kvm.h          |    2 +-
 qemu-kvm-x86.c |   12 ++++++------
 qemu-kvm.c     |    5 -----
 qemu-kvm.h     |   13 +------------
 8 files changed, 14 insertions(+), 30 deletions(-)

diff --git a/hw/i8254.c b/hw/i8254.c
index db9e94a..1add08e 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -491,7 +491,7 @@ void hpet_disable_pit(void)
 {
     PITChannelState *s = &pit_state.channels[0];
 
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
+    if (kvm_enabled() && kvm_pit_in_kernel()) {
         if (qemu_kvm_has_pit_state2()) {
             kvm_hpet_disable_kpit();
         } else {
@@ -515,7 +515,7 @@ void hpet_enable_pit(void)
     PITState *pit = &pit_state;
     PITChannelState *s = &pit->channels[0];
 
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
+    if (kvm_enabled() && kvm_pit_in_kernel()) {
         if (qemu_kvm_has_pit_state2()) {
             kvm_hpet_enable_kpit();
         } else {
diff --git a/hw/pc.c b/hw/pc.c
index 55df58d..7add660 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -950,7 +950,7 @@ static void pc_init1(ram_addr_t ram_size,
         ioapic_irq_hack = isa_irq;
     }
 #ifdef CONFIG_KVM_PIT
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel())
+    if (kvm_enabled() && kvm_pit_in_kernel())
 	pit = kvm_pit_init(0x40, isa_reserve_irq(0));
     else
 #endif
diff --git a/hw/pcspk.c b/hw/pcspk.c
index 128836b..fb5f763 100644
--- a/hw/pcspk.c
+++ b/hw/pcspk.c
@@ -56,7 +56,7 @@ static void kvm_get_pit_ch2(PITState *pit,
 {
     struct kvm_pit_state pit_state;
 
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
+    if (kvm_enabled() && kvm_pit_in_kernel()) {
         kvm_get_pit(kvm_context, &pit_state);
         pit->channels[2].mode = pit_state.channels[2].mode;
         pit->channels[2].count = pit_state.channels[2].count;
@@ -71,7 +71,7 @@ static void kvm_get_pit_ch2(PITState *pit,
 static void kvm_set_pit_ch2(PITState *pit,
                             struct kvm_pit_state *inkernel_state)
 {
-    if (kvm_enabled() && qemu_kvm_pit_in_kernel()) {
+    if (kvm_enabled() && kvm_pit_in_kernel()) {
         inkernel_state->channels[2].mode = pit->channels[2].mode;
         inkernel_state->channels[2].count = pit->channels[2].count;
         inkernel_state->channels[2].count_load_time =
diff --git a/kvm-all.c b/kvm-all.c
index b9c1553..2237239 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -167,13 +167,13 @@ int kvm_irqchip_in_kernel(void)
     return kvm_state->irqchip_in_kernel;
 }
 
-#ifdef KVM_UPSTREAM
 int kvm_pit_in_kernel(void)
 {
     return kvm_state->pit_in_kernel;
 }
 
 
+#ifdef KVM_UPSTREAM
 int kvm_init_vcpu(CPUState *env)
 {
     KVMState *s = kvm_state;
diff --git a/kvm.h b/kvm.h
index 7f32f95..2f97c64 100644
--- a/kvm.h
+++ b/kvm.h
@@ -61,10 +61,10 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type);
 void kvm_remove_all_breakpoints(CPUState *current_env);
 int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
+#endif /* KVM_UPSTREAM */
 
 int kvm_pit_in_kernel(void);
 int kvm_irqchip_in_kernel(void);
-#endif /* KVM_UPSTREAM */
 
 /* internal API */
 
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index a7bf446..2b36c22 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -119,13 +119,13 @@ static int kvm_create_pit(kvm_context_t kvm)
 #ifdef KVM_CAP_PIT
 	int r;
 
-	kvm->pit_in_kernel = 0;
+	kvm_state->pit_in_kernel = 0;
 	if (!kvm->no_pit_creation) {
 		r = kvm_ioctl(kvm_state, KVM_CHECK_EXTENSION, KVM_CAP_PIT);
 		if (r > 0) {
 			r = kvm_vm_ioctl(kvm_state, KVM_CREATE_PIT);
 			if (r >= 0)
-				kvm->pit_in_kernel = 1;
+				kvm_state->pit_in_kernel = 1;
 			else {
 				fprintf(stderr, "Create kernel PIC irqchip failed\n");
 				return r;
@@ -311,14 +311,14 @@ int kvm_set_lapic(CPUState *env, struct kvm_lapic_state *s)
 
 int kvm_get_pit(kvm_context_t kvm, struct kvm_pit_state *s)
 {
-	if (!kvm->pit_in_kernel)
+	if (!kvm_pit_in_kernel())
 		return 0;
 	return kvm_vm_ioctl(kvm_state, KVM_GET_PIT, s);
 }
 
 int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
 {
-	if (!kvm->pit_in_kernel)
+	if (!kvm_pit_in_kernel())
 		return 0;
 	return kvm_vm_ioctl(kvm_state, KVM_SET_PIT, s);
 }
@@ -326,14 +326,14 @@ int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
 #ifdef KVM_CAP_PIT_STATE2
 int kvm_get_pit2(kvm_context_t kvm, struct kvm_pit_state2 *ps2)
 {
-	if (!kvm->pit_in_kernel)
+	if (!kvm_pit_in_kernel())
 		return 0;
 	return kvm_vm_ioctl(kvm_state, KVM_GET_PIT2, ps2);
 }
 
 int kvm_set_pit2(kvm_context_t kvm, struct kvm_pit_state2 *ps2)
 {
-	if (!kvm->pit_in_kernel)
+	if (!kvm_pit_in_kernel())
 		return 0;
 	return kvm_vm_ioctl(kvm_state, KVM_SET_PIT2, ps2);
 }
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 5c4f6e6..9821fc5 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1049,11 +1049,6 @@ int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
     return r;
 }
 
-int kvm_pit_in_kernel(kvm_context_t kvm)
-{
-    return kvm->pit_in_kernel;
-}
-
 int kvm_inject_nmi(CPUState *env)
 {
 #ifdef KVM_CAP_USER_NMI
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 967162c..17017c4 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -64,8 +64,6 @@ struct kvm_context {
     int irqchip_inject_ioctl;
     /// do not create in-kernel pit if set
     int no_pit_creation;
-    /// in-kernel pit status
-    int pit_in_kernel;
 #ifdef KVM_CAP_IRQ_ROUTING
     struct kvm_irq_routing *irq_routes;
     int nr_allocated_irq_routes;
@@ -563,13 +561,6 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
                         int abort_on_error);
 
 /*!
- * \brief Query wheather in kernel pit is used
- *
- *  \param kvm Pointer to the current kvm_context
- */
-int kvm_pit_in_kernel(kvm_context_t kvm);
-
-/*!
  * \brief Initialize coalesced MMIO
  *
  * Check for coalesced MMIO capability and store in context
@@ -1014,7 +1005,6 @@ int kvm_arch_halt(CPUState *env);
 int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip,
                       int is_write);
 
-#define qemu_kvm_pit_in_kernel() kvm_pit_in_kernel(kvm_context)
 #define qemu_kvm_has_gsi_routing() kvm_has_gsi_routing(kvm_context)
 #ifdef TARGET_I386
 #define qemu_kvm_has_pit_state2() kvm_has_pit_state2(kvm_context)
@@ -1022,7 +1012,6 @@ int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip,
 void kvm_load_tsc(CPUState *env);
 #else
 #define kvm_nested 0
-#define qemu_kvm_pit_in_kernel() (0)
 #define qemu_kvm_has_gsi_routing() (0)
 #ifdef TARGET_I386
 #define qemu_kvm_has_pit_state2() (0)
@@ -1052,7 +1041,6 @@ static inline int kvm_set_migration_log(int enable)
 }
 
 
-int kvm_irqchip_in_kernel(void);
 #ifdef CONFIG_KVM
 
 typedef struct KVMSlot {
@@ -1080,6 +1068,7 @@ struct KVMState {
     QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;
 #endif
     int irqchip_in_kernel;
+    int pit_in_kernel;
 
     struct kvm_context kvm_context;
 };
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 8/9] KVM: Rework of guest debug state writing
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (6 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 7/9] qemu-kvm: Use upstream kvm_pit_in_kernel Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-21  9:26   ` [Qemu-devel] " Avi Kivity
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 9/9] qemu-kvm: Use upstream guest debug code Jan Kiszka
  2010-02-21  9:20 ` [Qemu-devel] Re: [PATCH 0/9] qemu-kvm: Extended use of upstream code Avi Kivity
  9 siblings, 1 reply; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

So far we synchronized any dirty VCPU state back into the kernel before
updating the guest debug state. This was a tribute to a deficite in x86
kernels before 2.6.33. But as this is an arch-dependent issue, it is
better handle in the x86 part of KVM and remove the writeback point for
generic code. This also avoids overwriting the flushed state later on if
user space decides to change some more registers before resuming the
guest.

We furthermore need to reinject guest exceptions via the appropriate
mechanism. That is KVM_SET_GUEST_DEBUG for older kernels and
KVM_SET_VCPU_EVENTS for recent ones. Using both mechanisms at the same
time will cause state corruptions.


Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c         |   12 ++++--------
 target-i386/kvm.c |   37 +++++++++++++++++++++++++++++++++----
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index 2237239..f0c5cf6 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -994,10 +994,6 @@ static void kvm_invoke_set_guest_debug(void *data)
     struct kvm_set_guest_debug_data *dbg_data = data;
     CPUState *env = dbg_data->env;
 
-    if (env->kvm_vcpu_dirty) {
-        kvm_arch_put_registers(env);
-        env->kvm_vcpu_dirty = 0;
-    }
     dbg_data->err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, &dbg_data->dbg);
 }
 
@@ -1005,12 +1001,12 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
 {
     struct kvm_set_guest_debug_data data;
 
-    data.dbg.control = 0;
-    if (env->singlestep_enabled)
-        data.dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
+    data.dbg.control = reinject_trap;
 
+    if (env->singlestep_enabled) {
+        data.dbg.control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
+    }
     kvm_arch_update_guest_debug(env, &data.dbg);
-    data.dbg.control |= reinject_trap;
     data.env = env;
 
     on_vcpu(env, kvm_invoke_set_guest_debug, &data);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 8743f32..a4130d4 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -885,6 +885,32 @@ int kvm_arch_put_registers(CPUState *env)
     if (ret < 0)
         return ret;
 
+    /*
+     * Kernels before 2.6.33 (which correlates with !kvm_has_vcpu_events())
+     * overwrote flags.TF injected via SET_GUEST_DEBUG while updating GP regs.
+     * Work around this by updating the debug state once again if
+     * single-stepping is on.
+     * Another reason to call kvm_update_guest_debug here is a pending debug
+     * trap raise by the guest. On kernels without SET_VCPU_EVENTS we have to
+     * reinject them via SET_GUEST_DEBUG.
+     */
+    if (!kvm_has_vcpu_events() &&
+        (env->exception_injected != -1 || env->singlestep_enabled)) {
+        unsigned long reinject_trap = 0;
+
+        if (env->exception_injected == 1) {
+            reinject_trap = KVM_GUESTDBG_INJECT_DB;
+        } else if (env->exception_injected == 3) {
+            reinject_trap = KVM_GUESTDBG_INJECT_BP;
+        }
+        env->exception_injected = -1;
+
+        ret = kvm_update_guest_debug(env, reinject_trap);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
     return 0;
 }
 
@@ -1130,10 +1156,13 @@ int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
     } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc))
         handle = 1;
 
-    if (!handle)
-        kvm_update_guest_debug(cpu_single_env,
-                        (arch_info->exception == 1) ?
-                        KVM_GUESTDBG_INJECT_DB : KVM_GUESTDBG_INJECT_BP);
+    if (!handle) {
+        cpu_synchronize_state(cpu_single_env);
+        assert(cpu_single_env->exception_injected == -1);
+
+        cpu_single_env->exception_injected = arch_info->exception;
+        cpu_single_env->has_error_code = 0;
+    }
 
     return handle;
 }
-- 
1.6.0.2

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

* [Qemu-devel] [PATCH 9/9] qemu-kvm: Use upstream guest debug code
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (7 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 8/9] KVM: Rework of guest debug state writing Jan Kiszka
@ 2010-02-19 18:22 ` Jan Kiszka
  2010-02-21  9:20 ` [Qemu-devel] Re: [PATCH 0/9] qemu-kvm: Extended use of upstream code Avi Kivity
  9 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2010-02-19 18:22 UTC (permalink / raw)
  To: Avi Kivity, Marcelo Tosatti
  Cc: Anthony Liguori, qemu-devel, kvm, Gleb Natapov

Code was absolute identical except for previous fixes and cleanup in
upstream.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 kvm-all.c         |    7 +-
 kvm.h             |    4 -
 qemu-kvm-x86.c    |  197 +++++++----------------------------------------------
 qemu-kvm.c        |   44 ------------
 qemu-kvm.h        |   37 ----------
 target-i386/kvm.c |    2 +-
 6 files changed, 30 insertions(+), 261 deletions(-)

diff --git a/kvm-all.c b/kvm-all.c
index f0c5cf6..bed562f 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -962,7 +962,9 @@ static void on_vcpu(CPUState *env, void (*func)(void *data), void *data)
 #endif
     func(data);
 }
-#endif /* KVM_UPSTREAM */
+#else /* !KVM_UPSTREAM */
+static void on_vcpu(CPUState *env, void (*func)(void *data), void *data);
+#endif /* !KVM_UPSTREAM */
 
 struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
                                                  target_ulong pc)
@@ -981,8 +983,6 @@ int kvm_sw_breakpoints_active(CPUState *env)
     return !QTAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
 }
 
-#ifdef KVM_UPSTREAM
-
 struct kvm_set_guest_debug_data {
     struct kvm_guest_debug dbg;
     CPUState *env;
@@ -1012,7 +1012,6 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
     on_vcpu(env, kvm_invoke_set_guest_debug, &data);
     return data.err;
 }
-#endif
 
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type)
diff --git a/kvm.h b/kvm.h
index 2f97c64..a78a27f 100644
--- a/kvm.h
+++ b/kvm.h
@@ -54,14 +54,12 @@ int kvm_coalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 int kvm_uncoalesce_mmio_region(target_phys_addr_t start, ram_addr_t size);
 void kvm_flush_coalesced_mmio_buffer(void);
 
-#ifdef KVM_UPSTREAM
 int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type);
 int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
                           target_ulong len, int type);
 void kvm_remove_all_breakpoints(CPUState *current_env);
 int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
-#endif /* KVM_UPSTREAM */
 
 int kvm_pit_in_kernel(void);
 int kvm_irqchip_in_kernel(void);
@@ -94,7 +92,6 @@ int kvm_arch_init(KVMState *s, int smp_cpus);
 int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
-#ifdef KVM_UPSTREAM
 
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
@@ -126,7 +123,6 @@ int kvm_arch_remove_hw_breakpoint(target_ulong addr,
 void kvm_arch_remove_all_hw_breakpoints(void);
 
 void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
-#endif
 
 int kvm_check_extension(KVMState *s, unsigned int extension);
 
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 2b36c22..bd3c0ab 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -921,6 +921,32 @@ void kvm_arch_load_regs(CPUState *env)
     rc = kvm_set_msrs(env, msrs, n);
     if (rc == -1)
         perror("kvm_set_msrs FAILED");
+
+    /*
+     * Kernels before 2.6.33 (which correlates with !kvm_has_vcpu_events())
+     * overwrote flags.TF injected via SET_GUEST_DEBUG while updating GP regs.
+     * Work around this by updating the debug state once again if
+     * single-stepping is on.
+     * Another reason to call kvm_update_guest_debug here is a pending debug
+     * trap raise by the guest. On kernels without SET_VCPU_EVENTS we have to
+     * reinject them via SET_GUEST_DEBUG.
+     */
+    if (!kvm_has_vcpu_events() &&
+        (env->exception_injected != -1 || env->singlestep_enabled)) {
+        unsigned long reinject_trap = 0;
+
+        if (env->exception_injected == 1) {
+            reinject_trap = KVM_GUESTDBG_INJECT_DB;
+        } else if (env->exception_injected == 3) {
+            reinject_trap = KVM_GUESTDBG_INJECT_BP;
+        }
+        env->exception_injected = -1;
+
+        rc = kvm_update_guest_debug(env, reinject_trap);
+        if (rc < 0) {
+            perror("kvm_update_guest_debug FAILED");
+        }
+    }
 }
 
 void kvm_load_tsc(CPUState *env)
@@ -1376,177 +1402,6 @@ void kvm_arch_cpu_reset(CPUState *env)
     }
 }
 
-int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
-{
-    uint8_t int3 = 0xcc;
-
-    if (cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 0) ||
-        cpu_memory_rw_debug(env, bp->pc, &int3, 1, 1))
-        return -EINVAL;
-    return 0;
-}
-
-int kvm_arch_remove_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
-{
-    uint8_t int3;
-
-    if (cpu_memory_rw_debug(env, bp->pc, &int3, 1, 0) || int3 != 0xcc ||
-        cpu_memory_rw_debug(env, bp->pc, (uint8_t *)&bp->saved_insn, 1, 1))
-        return -EINVAL;
-    return 0;
-}
-
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-static struct {
-    target_ulong addr;
-    int len;
-    int type;
-} hw_breakpoint[4];
-
-static int nb_hw_breakpoint;
-
-static int find_hw_breakpoint(target_ulong addr, int len, int type)
-{
-    int n;
-
-    for (n = 0; n < nb_hw_breakpoint; n++)
-	if (hw_breakpoint[n].addr == addr && hw_breakpoint[n].type == type &&
-	    (hw_breakpoint[n].len == len || len == -1))
-	    return n;
-    return -1;
-}
-
-int kvm_arch_insert_hw_breakpoint(target_ulong addr,
-                                  target_ulong len, int type)
-{
-    switch (type) {
-    case GDB_BREAKPOINT_HW:
-	len = 1;
-	break;
-    case GDB_WATCHPOINT_WRITE:
-    case GDB_WATCHPOINT_ACCESS:
-	switch (len) {
-	case 1:
-	    break;
-	case 2:
-	case 4:
-	case 8:
-	    if (addr & (len - 1))
-		return -EINVAL;
-	    break;
-	default:
-	    return -EINVAL;
-	}
-	break;
-    default:
-	return -ENOSYS;
-    }
-
-    if (nb_hw_breakpoint == 4)
-        return -ENOBUFS;
-
-    if (find_hw_breakpoint(addr, len, type) >= 0)
-        return -EEXIST;
-
-    hw_breakpoint[nb_hw_breakpoint].addr = addr;
-    hw_breakpoint[nb_hw_breakpoint].len = len;
-    hw_breakpoint[nb_hw_breakpoint].type = type;
-    nb_hw_breakpoint++;
-
-    return 0;
-}
-
-int kvm_arch_remove_hw_breakpoint(target_ulong addr,
-                                  target_ulong len, int type)
-{
-    int n;
-
-    n = find_hw_breakpoint(addr, (type == GDB_BREAKPOINT_HW) ? 1 : len, type);
-    if (n < 0)
-        return -ENOENT;
-
-    nb_hw_breakpoint--;
-    hw_breakpoint[n] = hw_breakpoint[nb_hw_breakpoint];
-
-    return 0;
-}
-
-void kvm_arch_remove_all_hw_breakpoints(void)
-{
-    nb_hw_breakpoint = 0;
-}
-
-static CPUWatchpoint hw_watchpoint;
-
-int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
-{
-    int handle = 0;
-    int n;
-
-    if (arch_info->exception == 1) {
-	if (arch_info->dr6 & (1 << 14)) {
-	    if (cpu_single_env->singlestep_enabled)
-		handle = 1;
-	} else {
-	    for (n = 0; n < 4; n++)
-		if (arch_info->dr6 & (1 << n))
-		    switch ((arch_info->dr7 >> (16 + n*4)) & 0x3) {
-		    case 0x0:
-			handle = 1;
-			break;
-		    case 0x1:
-			handle = 1;
-			cpu_single_env->watchpoint_hit = &hw_watchpoint;
-			hw_watchpoint.vaddr = hw_breakpoint[n].addr;
-			hw_watchpoint.flags = BP_MEM_WRITE;
-			break;
-		    case 0x3:
-			handle = 1;
-			cpu_single_env->watchpoint_hit = &hw_watchpoint;
-			hw_watchpoint.vaddr = hw_breakpoint[n].addr;
-			hw_watchpoint.flags = BP_MEM_ACCESS;
-			break;
-		    }
-	}
-    } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc))
-	handle = 1;
-
-    if (!handle)
-	kvm_update_guest_debug(cpu_single_env,
-			(arch_info->exception == 1) ?
-			KVM_GUESTDBG_INJECT_DB : KVM_GUESTDBG_INJECT_BP);
-
-    return handle;
-}
-
-void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
-{
-    const uint8_t type_code[] = {
-	[GDB_BREAKPOINT_HW] = 0x0,
-	[GDB_WATCHPOINT_WRITE] = 0x1,
-	[GDB_WATCHPOINT_ACCESS] = 0x3
-    };
-    const uint8_t len_code[] = {
-	[1] = 0x0, [2] = 0x1, [4] = 0x3, [8] = 0x2
-    };
-    int n;
-
-    if (kvm_sw_breakpoints_active(env))
-	dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
-
-    if (nb_hw_breakpoint > 0) {
-	dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_HW_BP;
-	dbg->arch.debugreg[7] = 0x0600;
-	for (n = 0; n < nb_hw_breakpoint; n++) {
-	    dbg->arch.debugreg[n] = hw_breakpoint[n].addr;
-	    dbg->arch.debugreg[7] |= (2 << (n * 2)) |
-		(type_code[hw_breakpoint[n].type] << (16 + n*4)) |
-		(len_code[hw_breakpoint[n].len] << (18 + n*4));
-	}
-    }
-}
-#endif
-
 #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT
 void kvm_arch_do_ioperm(void *_data)
 {
diff --git a/qemu-kvm.c b/qemu-kvm.c
index 9821fc5..3a169fc 100644
--- a/qemu-kvm.c
+++ b/qemu-kvm.c
@@ -1025,13 +1025,6 @@ int kvm_inject_irq(CPUState *env, unsigned irq)
     return kvm_vcpu_ioctl(env, KVM_INTERRUPT, &intr);
 }
 
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_set_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
-{
-    return kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, dbg);
-}
-#endif
-
 int kvm_set_signal_mask(CPUState *env, const sigset_t *sigset)
 {
     struct kvm_signal_mask *sigmask;
@@ -2312,43 +2305,6 @@ void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size,
     return;
 }
 
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-
-struct kvm_set_guest_debug_data {
-    struct kvm_guest_debug dbg;
-    int err;
-};
-
-static void kvm_invoke_set_guest_debug(void *data)
-{
-    struct kvm_set_guest_debug_data *dbg_data = data;
-
-    if (cpu_single_env->kvm_vcpu_dirty) {
-        kvm_arch_save_regs(cpu_single_env);
-        cpu_single_env->kvm_vcpu_dirty = 0;
-    }
-    dbg_data->err =
-        kvm_set_guest_debug(cpu_single_env,
-                            &dbg_data->dbg);
-}
-
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
-{
-    struct kvm_set_guest_debug_data data;
-
-    data.dbg.control = 0;
-    if (env->singlestep_enabled)
-        data.dbg.control = KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_SINGLESTEP;
-
-    kvm_arch_update_guest_debug(env, &data.dbg);
-    data.dbg.control |= reinject_trap;
-
-    on_vcpu(env, kvm_invoke_set_guest_debug, &data);
-    return data.err;
-}
-
-#endif
-
 /*
  * dirty pages logging
  */
diff --git a/qemu-kvm.h b/qemu-kvm.h
index 17017c4..93b144f 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -323,10 +323,6 @@ static inline int kvm_reset_mpstate(CPUState *env)
  */
 int kvm_inject_irq(CPUState *env, unsigned irq);
 
-#ifdef KVM_CAP_SET_GUEST_DEBUG
-int kvm_set_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
-#endif
-
 #if defined(__i386__) || defined(__x86_64__)
 /*!
  * \brief Setup a vcpu's cpuid instruction emulation
@@ -880,12 +876,6 @@ int kvm_init_ap(void);
 int kvm_vcpu_inited(CPUState *env);
 void kvm_load_mpstate(CPUState *env);
 void kvm_save_mpstate(CPUState *env);
-int kvm_insert_breakpoint(CPUState * current_env, target_ulong addr,
-                          target_ulong len, int type);
-int kvm_remove_breakpoint(CPUState * current_env, target_ulong addr,
-                          target_ulong len, int type);
-void kvm_remove_all_breakpoints(CPUState * current_env);
-int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap);
 void kvm_apic_init(CPUState *env);
 /* called from vcpu initialization */
 void qemu_kvm_load_lapic(CPUState *env);
@@ -928,33 +918,6 @@ void kvm_arch_push_nmi(void *opaque);
 void kvm_arch_cpu_reset(CPUState *env);
 int kvm_set_boot_cpu_id(uint32_t id);
 
-struct kvm_guest_debug;
-struct kvm_debug_exit_arch;
-
-struct kvm_sw_breakpoint {
-    target_ulong pc;
-    target_ulong saved_insn;
-    int use_count;
-    QTAILQ_ENTRY(kvm_sw_breakpoint) entry;
-};
-
-QTAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
-
-int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info);
-int kvm_sw_breakpoints_active(CPUState *env);
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
-                                                 target_ulong pc);
-int kvm_arch_insert_sw_breakpoint(CPUState * current_env,
-                                  struct kvm_sw_breakpoint *bp);
-int kvm_arch_remove_sw_breakpoint(CPUState * current_env,
-                                  struct kvm_sw_breakpoint *bp);
-int kvm_arch_insert_hw_breakpoint(target_ulong addr, target_ulong len,
-                                  int type);
-int kvm_arch_remove_hw_breakpoint(target_ulong addr, target_ulong len,
-                                  int type);
-void kvm_arch_remove_all_hw_breakpoints(void);
-void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg);
-
 void qemu_kvm_aio_wait_start(void);
 void qemu_kvm_aio_wait(void);
 void qemu_kvm_aio_wait_end(void);
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a4130d4..9e88932 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1020,6 +1020,7 @@ int kvm_arch_handle_exit(CPUState *env, struct kvm_run *run)
 
     return ret;
 }
+#endif
 
 #ifdef KVM_CAP_SET_GUEST_DEBUG
 int kvm_arch_insert_sw_breakpoint(CPUState *env, struct kvm_sw_breakpoint *bp)
@@ -1194,6 +1195,5 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
     }
 }
 #endif /* KVM_CAP_SET_GUEST_DEBUG */
-#endif
 
 #include "qemu-kvm-x86.c"
-- 
1.6.0.2

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

* [Qemu-devel] Re: [PATCH 0/9] qemu-kvm: Extended use of upstream code
  2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
                   ` (8 preceding siblings ...)
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 9/9] qemu-kvm: Use upstream guest debug code Jan Kiszka
@ 2010-02-21  9:20 ` Avi Kivity
  9 siblings, 0 replies; 13+ messages in thread
From: Avi Kivity @ 2010-02-21  9:20 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony Liguori, Marcelo Tosatti, qemu-devel, kvm, Gleb Natapov

On 02/19/2010 08:22 PM, Jan Kiszka wrote:
> Spin-off from my longer series as Marcelo asked for the last patch as
> the next step. I don't see any value in reordering the series, so I just
> but off the lower bits.
>
> This part mostly cleans up common KVM code that is also present
> upstream. It also includes the fixed guest debug writeback, first for
> upstream (patch 8 should be queued into uq/master as well), then merged
> into qemu-kvm while dropping the qemu-kvm copy of the guest debugging
> code.
>
> The differences to previous postings of the full series are:
>   - rebased over qemu-kvm
>   - fixed guest state writeback to avoid conflicts with SET_VCPU_EVENTS,
>     rather use them on modern kernels (I know Gleb will hate me for this,
>     but I'm convinced it's cleaner that way)
>
>    

Applied all, some issues pointed out as reply to individual patch.

-- 
error compiling committee.c: too many arguments to function

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

* [Qemu-devel] Re: [PATCH 2/9] qemu-kvm: Clean up register access API
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 2/9] qemu-kvm: Clean up register access API Jan Kiszka
@ 2010-02-21  9:25   ` Avi Kivity
  0 siblings, 0 replies; 13+ messages in thread
From: Avi Kivity @ 2010-02-21  9:25 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony Liguori, Marcelo Tosatti, qemu-devel, kvm, Gleb Natapov

On 02/19/2010 08:22 PM, Jan Kiszka wrote:
> qemu-kvm's functions for accessing the VCPU registers are
> kvm_arch_load/save_regs. Use them directly instead of going through
> various wrappers. Specifically, we do not need on_vcpu wrapping as all
> users either already run in the related thread or call while the vm is
> stopped. This is now also validated during runtime via asserts.
>
>
> +    assert(kvm_cpu_is_stopped(env) || env->thread_id == kvm_get_thread_id());
>    

The kvm_cpu_is_stopped() part is wrong, for two reasons.  First, a 
future ABI revolution might switch to syscalls and thus make the 
association between vcpu and thread implicit.  This will allow us to 
drop vcpu->mutex, eventually.  Second, kvm_cpu_is_stopped() will be racy 
in a threaded future version of qemu.  All vcpu ioctls should be made 
from the vcpu thread.

Documentation/kvm/api.txt has this to say about the matter:

>  - vcpu ioctls: These query and set attributes that control the operation
>    of a single virtual cpu.
>
>    Only run vcpu ioctls from the same thread that was used to create the
>    vcpu.

So it isn't just me.

-- 
error compiling committee.c: too many arguments to function

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

* [Qemu-devel] Re: [PATCH 8/9] KVM: Rework of guest debug state writing
  2010-02-19 18:22 ` [Qemu-devel] [PATCH 8/9] KVM: Rework of guest debug state writing Jan Kiszka
@ 2010-02-21  9:26   ` Avi Kivity
  0 siblings, 0 replies; 13+ messages in thread
From: Avi Kivity @ 2010-02-21  9:26 UTC (permalink / raw)
  To: Jan Kiszka
  Cc: Anthony Liguori, Marcelo Tosatti, qemu-devel, kvm, Gleb Natapov

On 02/19/2010 08:22 PM, Jan Kiszka wrote:
> So far we synchronized any dirty VCPU state back into the kernel before
> updating the guest debug state. This was a tribute to a deficite in x86
> kernels before 2.6.33. But as this is an arch-dependent issue, it is
> better handle in the x86 part of KVM and remove the writeback point for
> generic code. This also avoids overwriting the flushed state later on if
> user space decides to change some more registers before resuming the
> guest.
>    

Inferring one property of kvm.ko from another is not good, since it 
creates problems with backports.  Better to create a separate KVM_CAP_ 
for the issue you're testing (and we can retroactively apply it to 2.6.33).

-- 
error compiling committee.c: too many arguments to function

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

end of thread, other threads:[~2010-02-21  9:27 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-19 18:22 [Qemu-devel] [PATCH 0/9] qemu-kvm: Extended use of upstream code Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 1/9] qemu-kvm: Drop vmport changes Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 2/9] qemu-kvm: Clean up register access API Jan Kiszka
2010-02-21  9:25   ` [Qemu-devel] " Avi Kivity
2010-02-19 18:22 ` [Qemu-devel] [PATCH 3/9] qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 4/9] qemu-kvm: Use upstream kvm_setup_guest_memory Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 5/9] qemu-kvm: Use some more upstream prototypes Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 6/9] qemu-kvm: Use upstream kvm_arch_get_supported_cpuid Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 7/9] qemu-kvm: Use upstream kvm_pit_in_kernel Jan Kiszka
2010-02-19 18:22 ` [Qemu-devel] [PATCH 8/9] KVM: Rework of guest debug state writing Jan Kiszka
2010-02-21  9:26   ` [Qemu-devel] " Avi Kivity
2010-02-19 18:22 ` [Qemu-devel] [PATCH 9/9] qemu-kvm: Use upstream guest debug code Jan Kiszka
2010-02-21  9:20 ` [Qemu-devel] Re: [PATCH 0/9] qemu-kvm: Extended use of upstream code Avi Kivity

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).