[PATCH 1/4] kvmppc: guest debug definitions
Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { + __u32 exception; + __u32 pc; + __u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { + struct { + __u32 addr; + __u32 type; + } bp[6]; }; #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5e5bae7..a364832 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -157,6 +157,18 @@ struct hpte_cache { struct kvmppc_pte pte; }; +struct kvmppc_debug_reg { + u32 dbcr0; + u32 iac[0]; + u32 iac1; + u32 iac2; + u32 iac3; + u32 iac4; + u32 dac[0]; + u32 dac1; + u32 dac2; +}; + struct kvm_vcpu_arch { ulong host_stack; u32 host_pid; @@ -240,6 +252,9 @@ struct kvm_vcpu_arch { u32 dbcr1; u32 dbsr; + struct kvmppc_debug_reg shadow_dbg_reg; + struct kvmppc_debug_reg host_dbg_reg; + #ifdef CONFIG_KVM_EXIT_TIMING struct kvmppc_exit_timing timing_exit; struct kvmppc_exit_timing timing_last_enter; @@ -274,6 +289,7 @@ struct kvm_vcpu_arch { struct tasklet_struct tasklet; u64 dec_jiffies; unsigned long pending_exceptions; + struct kvm_guest_debug_arch dbg; #ifdef CONFIG_PPC64 struct hpte_cache hpte_cache[HPTEG_CACHE_NUM]; -- 1.6.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND 0/4] kvmppc/booke: add guest debug support
This patchset add guest debug support for booke. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] kvmppc/booke: switch shadow/host debug registers on guest enter/exit path
This provide a precise way to avoid confounding settings of guest and host. Also the guest hardware emulation about debug can be implemented based on this. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kernel/asm-offsets.c |3 ++ arch/powerpc/kvm/booke_interrupts.S | 58 +++ 2 files changed, 61 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 957ceb7..67e978d 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -425,6 +425,9 @@ int main(void) DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); + DEFINE(VCPU_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg)); + DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg)); + DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug)); /* book3s_64 */ #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 380a78c..644ff1d 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -168,6 +168,26 @@ _GLOBAL(kvmppc_resume_host) stw r9, VCPU_FAULT_ESR(r4) ..skip_esr: + lwz r6, VCPU_GUEST_DEBUG(r4) + or. r6, r6, r6 + beq ..skip_load_host_debug + addir7, r4, VCPU_HOST_DBG - 4 + lwzur9, 4(r7) + mtspr SPRN_DBCR0, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC1, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC2, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC3, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC4, r9 + lwzur9, 4(r7) + mtspr SPRN_DAC1, r9 + lwzur9, 4(r7) + mtspr SPRN_DAC2, r9 +..skip_load_host_debug: + /* Save remaining volatile guest register state to vcpu. */ stw r0, VCPU_GPR(r0)(r4) stw r1, VCPU_GPR(r1)(r4) @@ -392,6 +412,44 @@ lightweight_exit: lwz r3, VCPU_SPRG7(r4) mtspr SPRN_SPRG7W, r3 + lwz r6, VCPU_GUEST_DEBUG(r4) + or. r6, r6, r6 + beq ..skip_load_guest_debug + mfmsr r7 + rlwinm r7, r7, 0, ~MSR_DE + mtmsr r7 + addir7, r4, VCPU_HOST_DBG - 4 + mfspr r8, SPRN_DBCR0 + stwur8, 4(r7) + mfspr r8, SPRN_IAC1 + stwur8, 4(r7) + mfspr r8, SPRN_IAC2 + stwur8, 4(r7) + mfspr r8, SPRN_IAC3 + stwur8, 4(r7) + mfspr r8, SPRN_IAC4 + stwur8, 4(r7) + mfspr r8, SPRN_DAC1 + stwur8, 4(r7) + mfspr r8, SPRN_DAC2 + stwur8, 4(r7) + addir7, r4, VCPU_SHADOW_DBG - 4 + lwzur8, 4(r7) + mtspr SPRN_DBCR0, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC1, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC2, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC3, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC4, r8 + lwzur8, 4(r7) + mtspr SPRN_DAC1, r8 + lwzur8, 4(r7) + mtspr SPRN_DAC2, r8 +..skip_load_guest_debug: + #ifdef CONFIG_KVM_EXIT_TIMING /* save enter time */ 1: -- 1.6.4 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] kvmppc/booke: guest debug support
According to user's gdb command, we set the corresponding debug control bits in shadow. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm_ppc.h |3 + arch/powerpc/kvm/booke.c | 93 ++-- arch/powerpc/kvm/e500.c|8 --- arch/powerpc/kvm/powerpc.c |2 +- 4 files changed, 93 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index e264282..8918aac 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -94,6 +94,9 @@ extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs); extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt); +extern int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu, + struct kvm_guest_debug *dbg); + extern int kvmppc_booke_init(void); extern void kvmppc_booke_exit(void); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 4d686cc..ec2722d 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -267,6 +267,16 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; } + if (unlikely(vcpu-guest_debug KVM_GUESTDBG_ENABLE) +(vcpu-arch.last_inst == KVM_INST_GUESTGDB)) { + run-exit_reason = KVM_EXIT_DEBUG; + run-debug.arch.pc = vcpu-arch.pc; + run-debug.arch.exception = exit_nr; + kvmppc_account_exit(vcpu, DEBUG_EXITS); + r = RESUME_HOST; + break; + } + er = kvmppc_emulate_instruction(run, vcpu); switch (er) { case EMULATE_DONE: @@ -293,6 +303,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, default: BUG(); } + + if (unlikely(vcpu-guest_debug KVM_GUESTDBG_ENABLE) + (vcpu-guest_debug KVM_GUESTDBG_SINGLESTEP)) { + run-exit_reason = KVM_EXIT_DEBUG; + r = RESUME_HOST; + } break; case BOOKE_INTERRUPT_FP_UNAVAIL: @@ -421,12 +437,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, u32 dbsr; vcpu-arch.pc = mfspr(SPRN_CSRR0); - - /* clear IAC events in DBSR register */ dbsr = mfspr(SPRN_DBSR); - dbsr = DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4; - mtspr(SPRN_DBSR, dbsr); + run-debug.arch.pc = vcpu-arch.pc; + run-debug.arch.status = 0; + + if (dbsr (DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4)) { + run-debug.arch.status |= KVMPPC_DEBUG_BREAKPOINT; + } else { + if (dbsr (DBSR_DAC1W | DBSR_DAC2W)) + run-debug.arch.status |= KVMPPC_DEBUG_WATCH_WRITE; + else if (dbsr (DBSR_DAC1R | DBSR_DAC2R)) + run-debug.arch.status |= KVMPPC_DEBUG_WATCH_READ; + if (dbsr (DBSR_DAC1R | DBSR_DAC1W)) + run-debug.arch.pc = vcpu-arch.shadow_dbg_reg.dac1; + else if (dbsr (DBSR_DAC2R | DBSR_DAC2W)) + run-debug.arch.pc = vcpu-arch.shadow_dbg_reg.dac2; + } + /* clear events in DBSR register */ + mtspr(SPRN_DBSR, ~0); + + run-debug.arch.exception = exit_nr; run-exit_reason = KVM_EXIT_DEBUG; kvmppc_account_exit(vcpu, DEBUG_EXITS); r = RESUME_HOST; @@ -560,6 +591,60 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) return -ENOTSUPP; } +int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu, +struct kvm_guest_debug *dbg) +{ + if (!(dbg-control KVM_GUESTDBG_ENABLE)) { + vcpu-guest_debug = 0; + return 0; + } + + vcpu-guest_debug = dbg-control; + vcpu-arch.shadow_dbg_reg.dbcr0 = 0; + + if (vcpu-guest_debug KVM_GUESTDBG_SINGLESTEP) + vcpu-arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC; + + if (vcpu-guest_debug KVM_GUESTDBG_USE_HW_BP) { + struct kvmppc_debug_reg *gdbgr = (vcpu-arch.shadow_dbg_reg); + int n, b = 0, w = 0; + const u32 bp_code[] = { + DBCR0_IAC1 | DBCR0_IDM, + DBCR0_IAC2 | DBCR0_IDM, + DBCR0_IAC3 | DBCR0_IDM, + DBCR0_IAC4 | DBCR0_IDM +
[PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 +++ arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof(kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) +{ + int gtlb_index; + gpa_t gpa; + gfn_t gfn; + struct page *page; + void *headdr, *from; + + /* Check the guest TLB. */ + gtlb_index = kvmppc_mmu_itlb_index(vcpu, geaddr); + if (gtlb_index 0) + return -EFAULT; + + gpa = kvmppc_mmu_xlate(vcpu, gtlb_index, geaddr); + gfn = gpa PAGE_SHIFT; + + page = gfn_to_page(vcpu-kvm, gfn); + if (page == bad_page) + return -EFAULT; + + headdr = kmap_atomic(page, KM_USER0); + if (!headdr) + return -EFAULT; + from = headdr + (geaddr (PAGE_SIZE - 1)); + memcpy(data, from, len); + kunmap_atomic(headdr, KM_USER0); + + return 0; +} + +static unsigned int kvmppc_guest_debug_exitnr_fixup(struct kvm_vcpu *vcpu, + unsigned int exit_nr) +{ + unsigned int ret = exit_nr; + + u32 csrr0 = mfspr(SPRN_CSRR0); + u32 dbsr = mfspr(SPRN_DBSR); + + if ((dbsr | DBSR_IC) + csrr0 = kvmppc_booke_handlers + csrr0 kvmppc_booke_handlers + (PAGE_SIZE VCPU_SIZE_ORDER)) { + int i = 0; + + for (i = 0; i handler_vector_num; i++) { + if (kvmppc_booke_handler_addr[i] + csrr0 == kvmppc_booke_handler_addr[i] + 4) { + mtspr(SPRN_DBSR, ~0); + ret = i; + break; + } + } + + } + + switch (ret) { + case BOOKE_INTERRUPT_DEBUG: + case BOOKE_INTERRUPT_ITLB_MISS: + case BOOKE_INTERRUPT_EXTERNAL: + case BOOKE_INTERRUPT_DECREMENTER: + break; + + case BOOKE_INTERRUPT_PROGRAM: + case BOOKE_INTERRUPT_DTLB_MISS: + /* Need to save the last instruction */ + kvmppc_read_guest(vcpu, vcpu-arch.pc, vcpu-arch.last_inst, 4); + break; + default: + printk(Unhandled debug after interrupt:%d\n, ret); + } + + return ret; +} + /** * kvmppc_handle_exit * @@ -233,6 +310,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run-exit_reason = KVM_EXIT_UNKNOWN; run-ready_for_interrupt_injection = 1; + if (unlikely(exit_nr == BOOKE_INTERRUPT_DEBUG)) + exit_nr = kvmppc_guest_debug_exitnr_fixup(vcpu, exit_nr); + switch (exit_nr) { case BOOKE_INTERRUPT_MACHINE_CHECK: printk(MACHINE CHECK: %lx\n, mfspr(SPRN_MCSR)); @@ -686,6 +766,8 @@ int __init kvmppc_booke_init(void) memcpy((void *)kvmppc_booke_handlers + ivor[i], kvmppc_handlers_start + i * kvmppc_handler_len, kvmppc_handler_len); + kvmppc_booke_handler_addr[i] = + (unsigned long)kvmppc_booke_handlers + ivor[i]; } flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 644ff1d..fdc48c1 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -42,16 +42,17 @@ #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ #define NEED_INST_MASK ((1BOOKE_INTERRUPT_PROGRAM)
Re: [PATCH 0/1] virtio_net: remove send queue
The patch can still apply to net-next cleanly. netperf results for removing send queue gain on my laptop (guest to host test) is around 20%. See below: Before: --- [r...@localhost ~]# netperf -H 192.168.122.1 -c -C -l60 -t TCP_STREAM Recv SendSendUtilization Service Demand Socket Socket Message Elapsed Send Recv Send Recv Size SizeSize Time Throughput localremote local remote bytes bytes bytessecs.10^6bits/s % S % S us/KB us/KB 87380 16384 1638460.03 3230.30 99.7585.842.530 4.354 After: -- Recv SendSend Utilization Service Demand Socket Socket Message Elapsed Send Recv Send Recv Size SizeSize Time Throughput localremote local remote bytes bytes bytessecs.10^6bits/s % S % S us/KB us/KB 87380 16384 1638460.02 4038.13 99.6285.792.021 3.481 Thanks Shirley -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RESEND 0/4] kvmppc/booke: add guest debug support
Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: This patchset add guest debug support for booke. I'd like to see an ack from Jan here. Some code looks like it uses generic interfaces. Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 04/21] KVM: x86: Fix up misreported CPU features
From qemu-kvm: Kernels before 2.6.30 misreported some essential CPU features via KVM_GET_SUPPORTED_CPUID. Fix them up. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- target-i386/kvm.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 504f501..9fb96b5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -101,12 +101,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) break; case R_EDX: ret = cpuid-entries[i].edx; -if (function == 0x8001) { +switch (function) { +case 1: +/* KVM before 2.6.30 misreports the following features */ +ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA; +break; +case 0x8001: /* On Intel, kvm returns cpuid according to the Intel spec, * so add missing bits according to the AMD spec: */ cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX); ret |= cpuid_1_edx 0xdfeff7ff; +break; } break; } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 07/21] qemu-kvm: Use some more upstream prototypes
Drop our private typedef of KVMState and use more identical upstream prototypes. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm.h | 10 +++--- qemu-kvm.c |4 +++- qemu-kvm.h | 24 +++- 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/kvm.h b/kvm.h index 05ee540..b5ed744 100644 --- a/kvm.h +++ b/kvm.h @@ -32,11 +32,13 @@ struct kvm_run; /* external API */ int kvm_init(int smp_cpus); +#endif /* KVM_UPSTREAM */ int kvm_init_vcpu(CPUState *env); int kvm_cpu_exec(CPUState *env); +#ifdef KVM_UPSTREAM void kvm_set_phys_mem(target_phys_addr_t start_addr, ram_addr_t size, ram_addr_t phys_offset); @@ -47,19 +49,19 @@ int kvm_physical_sync_dirty_bitmap(target_phys_addr_t start_addr, 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_set_migration_log(int enable); +#endif /* KVM_UPSTREAM */ 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); 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); +#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, @@ -69,6 +71,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 */ @@ -97,7 +100,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 @@ -131,9 +133,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 b153ee1..a8f02fc 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -1909,12 +1909,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 de00763..b34b39f 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,8 +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); int kvm_arch_init_irq_routing(void); @@ -1021,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) @@ -1040,10 +1031,6 @@ void
[PATCH v2 02/21] KVM: Make vmport KVM-compatible
The vmport device accesses the VCPU registers, so it requires proper cpu_synchronize_state. Add it to vmport_ioport_read, which also synchronizes vmport_ioport_write. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/vmport.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/vmport.c b/hw/vmport.c index 884af3f..6c9d7c9 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -25,6 +25,7 @@ #include isa.h #include pc.h #include sysemu.h +#include kvm.h //#define VMPORT_DEBUG @@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) unsigned char command; uint32_t eax; +cpu_synchronize_state(env); + eax = env-regs[R_EAX]; if (eax != VMPORT_MAGIC) return eax; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 17/21] qemu-kvm: Use VCPU event state for reset and vmsave/load
Push reading/writing of vcpu_events into kvm_arch_load/save_regs to avoid KVM-specific hooks in generic code. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm.h |2 -- qemu-kvm-x86.c|6 -- target-i386/kvm.c |4 ++-- target-i386/machine.c |6 -- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/kvm.h b/kvm.h index e4005d8..686ee33 100644 --- a/kvm.h +++ b/kvm.h @@ -53,8 +53,6 @@ int kvm_set_migration_log(int enable); int kvm_has_sync_mmu(void); int kvm_has_vcpu_events(void); -int kvm_put_vcpu_events(CPUState *env, int level); -int kvm_get_vcpu_events(CPUState *env); void kvm_setup_guest_memory(void *start, size_t size); diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index 0d2cce8..23a23eb 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -986,6 +986,8 @@ void kvm_arch_load_regs(CPUState *env, int level) /* Avoid deadlock: no user space IRQ will ever clear it. */ env-halted = 0; } + +kvm_put_vcpu_events(env, level); } void kvm_load_tsc(CPUState *env) @@ -1157,6 +1159,7 @@ void kvm_arch_save_regs(CPUState *env) } } kvm_arch_save_mpstate(env); +kvm_get_vcpu_events(env); } static void do_cpuid_ent(struct kvm_cpuid_entry2 *e, uint32_t function, @@ -1231,7 +1234,7 @@ int kvm_arch_init_vcpu(CPUState *cenv) qemu_kvm_load_lapic(cenv); -cenv-interrupt_injected = -1; +kvm_arch_reset_vcpu(cenv); #ifdef KVM_CPUID_SIGNATURE /* Paravirtualization CPUIDs */ @@ -1398,7 +1401,6 @@ void kvm_arch_push_nmi(void *opaque) void kvm_arch_cpu_reset(CPUState *env) { kvm_arch_reset_vcpu(env); -kvm_put_vcpu_events(env, KVM_PUT_RESET_STATE); kvm_reset_mpstate(env); if (!cpu_is_bsp(env) !kvm_irqchip_in_kernel()) { env-interrupt_request = ~CPU_INTERRUPT_HARD; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index fefd5a5..9bd2952 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -789,7 +789,7 @@ static int kvm_get_mp_state(CPUState *env) } #endif -int kvm_put_vcpu_events(CPUState *env, int level) +static int kvm_put_vcpu_events(CPUState *env, int level) { #ifdef KVM_CAP_VCPU_EVENTS struct kvm_vcpu_events events; @@ -825,7 +825,7 @@ int kvm_put_vcpu_events(CPUState *env, int level) #endif } -int kvm_get_vcpu_events(CPUState *env) +static int kvm_get_vcpu_events(CPUState *env) { #ifdef KVM_CAP_VCPU_EVENTS struct kvm_vcpu_events events; diff --git a/target-i386/machine.c b/target-i386/machine.c index 6fca559..bcc315b 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -5,7 +5,6 @@ #include exec-all.h #include kvm.h -#include qemu-kvm.h static const VMStateDescription vmstate_segment = { .name = segment, @@ -322,10 +321,6 @@ static void cpu_pre_save(void *opaque) CPUState *env = opaque; int i; -if (kvm_enabled()) { -kvm_get_vcpu_events(env); -} - /* FPU */ env-fpus_vmstate = (env-fpus ~0x3800) | (env-fpstt 0x7) 11; env-fptag_vmstate = 0; @@ -362,7 +357,6 @@ static int cpu_post_load(void *opaque, int version_id) if (kvm_enabled()) { kvm_load_tsc(env); -kvm_put_vcpu_events(env, KVM_PUT_FULL_STATE); } return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 12/21] qemu-kvm: Use upstream kvm_vcpu_dirty
Drop regs_modified in favor of upstream's equivalent and clean up kvm_cpu_synchronize_state at this chance. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- cpu-defs.h |1 - hw/pc.c|2 +- qemu-kvm.c | 18 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 49a9e8d..c57d8df 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -142,7 +142,6 @@ struct KVMCPUState { pthread_t thread; int signalled; struct qemu_work_item *queued_work_first, *queued_work_last; -int regs_modified; }; #define CPU_TEMP_BUF_NLONGS 128 diff --git a/hw/pc.c b/hw/pc.c index 7a7dfa7..af6ea8b 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -744,7 +744,7 @@ CPUState *pc_new_cpu(const char *cpu_model) fprintf(stderr, Unable to find x86 CPU definition\n); exit(1); } -env-kvm_cpu_state.regs_modified = 1; +env-kvm_vcpu_dirty = 1; if ((env-cpuid_features CPUID_APIC) || smp_cpus 1) { env-cpuid_apic_id = env-cpu_index; /* APIC reset callback resets cpu */ diff --git a/qemu-kvm.c b/qemu-kvm.c index 0094db9..6a72b89 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -861,9 +861,9 @@ int pre_kvm_run(kvm_context_t kvm, CPUState *env) { kvm_arch_pre_run(env, env-kvm_run); -if (env-kvm_cpu_state.regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_load_regs(env); -env-kvm_cpu_state.regs_modified = 0; +env-kvm_vcpu_dirty = 0; } pthread_mutex_unlock(qemu_mutex); @@ -1530,16 +1530,16 @@ static void on_vcpu(CPUState *env, void (*func)(void *data), void *data) static void do_kvm_cpu_synchronize_state(void *_env) { CPUState *env = _env; -if (!env-kvm_cpu_state.regs_modified) { -kvm_arch_save_regs(env); -env-kvm_cpu_state.regs_modified = 1; -} + +kvm_arch_save_regs(env); } void kvm_cpu_synchronize_state(CPUState *env) { -if (!env-kvm_cpu_state.regs_modified) +if (!env-kvm_vcpu_dirty) { on_vcpu(env, do_kvm_cpu_synchronize_state, env); +env-kvm_vcpu_dirty = 1; +} } static void inject_interrupt(void *data) @@ -2329,9 +2329,9 @@ static void kvm_invoke_set_guest_debug(void *data) { struct kvm_set_guest_debug_data *dbg_data = data; -if (cpu_single_env-kvm_cpu_state.regs_modified) { +if (cpu_single_env-kvm_vcpu_dirty) { kvm_arch_save_regs(cpu_single_env); -cpu_single_env-kvm_cpu_state.regs_modified = 0; +cpu_single_env-kvm_vcpu_dirty = 0; } dbg_data-err = kvm_set_guest_debug(cpu_single_env, -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 00/21] qemu-kvm: Hook cleanups and extended use of upstream code
This version addresses the feedback on v2, namely: - assert(vm stopped || current thread == env-thread) on low-level load/save registers - fixed mpstate initialization Yet untested is -no-kvm-irqchip with smp due to some bug in unpatched qemu-kvm or the kernel modules. Still investigating. Pull URL is still git://git.kiszka.org/qemu-kvm.git queues/vcpu-state PS: The corresponding upstream queue is now available under queues/kvm-upstream in the same repository. Will send it out later if there are no further remarks on this series to avoid flooding the mailing lists. Early testers are nevertheless welcome. Jan Kiszka (21): qemu-kvm: Drop vmport changes KVM: Make vmport KVM-compatible qemu-kvm: Clean up register access API KVM: x86: Fix up misreported CPU features 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: Move and rename regs_modified KVM: Rework of guest debug state writing qemu-kvm: Use upstream kvm_vcpu_dirty qemu-kvm: Use upstream guest debug code qemu-kvm: Rework VCPU state writeback API qemu-kvm: Clean up mpstate synchronization KVM: x86: Restrict writeback of VCPU state qemu-kvm: Use VCPU event state for reset and vmsave/load qemu-kvm: Cleanup/fix TSC and PV clock writeback qemu-kvm: Clean up KVM's APIC hooks qemu-kvm: Move kvm_set_boot_cpu_id qemu-kvm: Bring qemu_init_vcpu back home cpu-defs.h|2 +- exec.c| 17 -- hw/apic.c | 47 +- hw/i8254.c|6 +- hw/i8259.c|2 +- hw/ioapic.c |2 +- hw/msix.c |3 +- hw/pc.c | 13 +-- hw/pcspk.c|4 +- hw/piix_pci.c |2 +- hw/ppc_newworld.c |3 - hw/ppc_oldworld.c |3 - hw/s390-virtio.c |1 - hw/vmport.c | 14 +-- kvm-all.c | 51 +++--- kvm.h | 35 +++-- qemu-kvm-ia64.c |6 +- qemu-kvm-x86.c| 433 +++-- qemu-kvm.c| 165 +++ qemu-kvm.h| 161 ++- savevm.c |4 + sysemu.h |4 + target-i386/cpu.h |9 +- target-i386/helper.c |2 + target-i386/kvm.c | 61 +-- target-i386/machine.c | 27 --- target-ia64/machine.c |5 +- target-ppc/kvm.c |2 +- target-ppc/machine.c |4 - target-s390x/kvm.c|3 +- vl.c | 32 - 31 files changed, 298 insertions(+), 825 deletions(-) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 16/21] KVM: x86: Restrict writeback of VCPU state
Do not write nmi_pending, sipi_vector, and mpstate unless we at least go through a reset. And TSC as well as KVM wallclocks should only be written on full sync, otherwise we risk to drop some time on during state read-modify-write. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm.h |2 +- qemu-kvm-x86.c|2 +- target-i386/kvm.c | 32 target-i386/machine.c |2 +- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/kvm.h b/kvm.h index ee8b3f6..e4005d8 100644 --- a/kvm.h +++ b/kvm.h @@ -53,7 +53,7 @@ int kvm_set_migration_log(int enable); int kvm_has_sync_mmu(void); int kvm_has_vcpu_events(void); -int kvm_put_vcpu_events(CPUState *env); +int kvm_put_vcpu_events(CPUState *env, int level); int kvm_get_vcpu_events(CPUState *env); void kvm_setup_guest_memory(void *start, size_t size); diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index c6cf317..0d2cce8 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -1398,7 +1398,7 @@ void kvm_arch_push_nmi(void *opaque) void kvm_arch_cpu_reset(CPUState *env) { kvm_arch_reset_vcpu(env); -kvm_put_vcpu_events(env); +kvm_put_vcpu_events(env, KVM_PUT_RESET_STATE); kvm_reset_mpstate(env); if (!cpu_is_bsp(env) !kvm_irqchip_in_kernel()) { env-interrupt_request = ~CPU_INTERRUPT_HARD; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 4a0c8bb..fefd5a5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -544,7 +544,7 @@ static void kvm_msr_entry_set(struct kvm_msr_entry *entry, entry-data = value; } -static int kvm_put_msrs(CPUState *env) +static int kvm_put_msrs(CPUState *env, int level) { struct { struct kvm_msrs info; @@ -558,7 +558,6 @@ static int kvm_put_msrs(CPUState *env) kvm_msr_entry_set(msrs[n++], MSR_IA32_SYSENTER_EIP, env-sysenter_eip); if (kvm_has_msr_star(env)) kvm_msr_entry_set(msrs[n++], MSR_STAR, env-star); -kvm_msr_entry_set(msrs[n++], MSR_IA32_TSC, env-tsc); kvm_msr_entry_set(msrs[n++], MSR_VM_HSAVE_PA, env-vm_hsave); #ifdef TARGET_X86_64 /* FIXME if lm capable */ @@ -567,8 +566,12 @@ static int kvm_put_msrs(CPUState *env) kvm_msr_entry_set(msrs[n++], MSR_FMASK, env-fmask); kvm_msr_entry_set(msrs[n++], MSR_LSTAR, env-lstar); #endif -kvm_msr_entry_set(msrs[n++], MSR_KVM_SYSTEM_TIME, env-system_time_msr); -kvm_msr_entry_set(msrs[n++], MSR_KVM_WALL_CLOCK, env-wall_clock_msr); +if (level == KVM_PUT_FULL_STATE) { +kvm_msr_entry_set(msrs[n++], MSR_IA32_TSC, env-tsc); +kvm_msr_entry_set(msrs[n++], MSR_KVM_SYSTEM_TIME, + env-system_time_msr); +kvm_msr_entry_set(msrs[n++], MSR_KVM_WALL_CLOCK, env-wall_clock_msr); +} msr_data.info.nmsrs = n; @@ -786,7 +789,7 @@ static int kvm_get_mp_state(CPUState *env) } #endif -int kvm_put_vcpu_events(CPUState *env) +int kvm_put_vcpu_events(CPUState *env, int level) { #ifdef KVM_CAP_VCPU_EVENTS struct kvm_vcpu_events events; @@ -810,8 +813,11 @@ int kvm_put_vcpu_events(CPUState *env) events.sipi_vector = env-sipi_vector; -events.flags = -KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR; +events.flags = 0; +if (level = KVM_PUT_RESET_STATE) { +events.flags |= +KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR; +} return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, events); #else @@ -882,15 +888,17 @@ int kvm_arch_put_registers(CPUState *env, int level) if (ret 0) return ret; -ret = kvm_put_msrs(env); +ret = kvm_put_msrs(env, level); if (ret 0) return ret; -ret = kvm_put_mp_state(env); -if (ret 0) -return ret; +if (level = KVM_PUT_RESET_STATE) { +ret = kvm_put_mp_state(env); +if (ret 0) +return ret; +} -ret = kvm_put_vcpu_events(env); +ret = kvm_put_vcpu_events(env, level); if (ret 0) return ret; diff --git a/target-i386/machine.c b/target-i386/machine.c index 61e6a87..6fca559 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -362,7 +362,7 @@ static int cpu_post_load(void *opaque, int version_id) if (kvm_enabled()) { kvm_load_tsc(env); -kvm_put_vcpu_events(env); +kvm_put_vcpu_events(env, KVM_PUT_FULL_STATE); } return 0; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 03/21] qemu-kvm: Clean up register access API
qemu-kvm's functios 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.kis...@siemens.com --- qemu-kvm-x86.c|4 qemu-kvm.c| 43 ++- qemu-kvm.h| 14 +++--- target-ia64/machine.c |4 ++-- 4 files changed, 15 insertions(+), 50 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 a305907..32e2873 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -862,7 +862,7 @@ int pre_kvm_run(kvm_context_t kvm, CPUState *env) kvm_arch_pre_run(env, env-kvm_run); if (env-kvm_cpu_state.regs_modified) { -kvm_arch_put_registers(env); +kvm_arch_load_regs(env); env-kvm_cpu_state.regs_modified = 0; } @@ -1429,7 +1429,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); } @@ -1532,16 +1532,11 @@ 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_cpu_state.regs_modified) { -kvm_arch_get_registers(env); +kvm_arch_save_regs(env); env-kvm_cpu_state.regs_modified = 1; } } @@ -1584,32 +1579,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; @@ -1653,7 +1622,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; } @@ -1880,7 +1849,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; @@ -2379,7 +2348,7 @@ static void kvm_invoke_set_guest_debug(void *data) struct kvm_set_guest_debug_data *dbg_data = data; if (cpu_single_env-kvm_cpu_state.regs_modified) { -kvm_arch_put_registers(cpu_single_env); +kvm_arch_save_regs(cpu_single_env); cpu_single_env-kvm_cpu_state.regs_modified = 0; } dbg_data-err = diff --git a/qemu-kvm.h b/qemu-kvm.h index 6b3e5a1..465aeac 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); @@ -1068,8 +1066,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) @@ -1098,13 +1094,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) -{
[PATCH v2 01/21] qemu-kvm: Drop vmport changes
This attempt to make vmport KVM compatible is half-broken and is scheduled to be replaced by proper upstream support. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/vmport.c | 13 + 1 files changed, 1 insertions(+), 12 deletions(-) diff --git a/hw/vmport.c b/hw/vmport.c index 648861b..884af3f 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 //#define VMPORT_DEBUG @@ -59,10 +57,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); eax = env-regs[R_EAX]; if (eax != VMPORT_MAGIC) @@ -79,12 +73,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 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 05/21] qemu-kvm: Use upstream kvm_enabled and cpu_synchronize_state
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.kis...@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 97e16ce..dac373e 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 9fa4e25..d0f4bbe 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 */ @@ -138,6 +137,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 */ @@ -150,5 +151,3 @@ static inline void cpu_synchronize_state(CPUState *env) } #endif - -#endif diff --git a/qemu-kvm.h b/qemu-kvm.h index 465aeac..a6e3271 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
[PATCH v2 06/21] qemu-kvm: Use upstream kvm_setup_guest_memory
Nothing missing in upstream kvm_setup_guest_memory, it is even more careful about error handling. Signed-off-by: Jan Kiszka jan.kis...@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 0423fff..e7fa605 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -886,7 +886,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()) { @@ -905,8 +904,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 d0f4bbe..05ee540 100644 --- a/kvm.h +++ b/kvm.h @@ -54,10 +54,9 @@ int kvm_has_vcpu_events(void); int kvm_put_vcpu_events(CPUState *env); int kvm_get_vcpu_events(CPUState *env); -#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); diff --git a/qemu-kvm.c b/qemu-kvm.c index 32e2873..b153ee1 100644 --- a/qemu-kvm.c +++ b/qemu-kvm.c @@ -2321,21 +2321,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 a6e3271..de00763 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 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 10/21] KVM: Move and rename regs_modified
Touching the user space representation of KVM's VCPU state is - naturally - a per-VCPU thing. So move the dirty flag into KVM_CPU_COMMON and rename it at this chance to reflect its true meaning. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- cpu-defs.h |1 + kvm-all.c | 12 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index cf502e9..49a9e8d 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -208,6 +208,7 @@ struct KVMCPUState { struct KVMState *kvm_state; \ struct kvm_run *kvm_run;\ int kvm_fd; \ +int kvm_vcpu_dirty; \ uint32_t stop; /* Stop request */ \ uint32_t stopped; /* Artificially stopped */\ struct KVMCPUState kvm_cpu_state; diff --git a/kvm-all.c b/kvm-all.c index 6cbca97..3516f01 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -573,9 +573,9 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run) void kvm_cpu_synchronize_state(CPUState *env) { -if (!env-kvm_state-regs_modified) { +if (!env-kvm_vcpu_dirty) { kvm_arch_get_registers(env); -env-kvm_state-regs_modified = 1; +env-kvm_vcpu_dirty = 1; } } @@ -593,9 +593,9 @@ int kvm_cpu_exec(CPUState *env) break; } -if (env-kvm_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } kvm_arch_pre_run(env, run); @@ -951,9 +951,9 @@ 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_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } dbg_data-err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, dbg_data-dbg); } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 19/21] qemu-kvm: Clean up KVM's APIC hooks
The APIC is part of the VCPU state, so trigger its readout and writeback from kvm_arch_save/load_regs. Thanks to the transparent sync on reset and vmsave/load, we can also drop explicit sync code, reducing the diff to upstream. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/apic.c | 37 + qemu-kvm-x86.c |4 ++-- qemu-kvm.h |5 ++--- 3 files changed, 9 insertions(+), 37 deletions(-) diff --git a/hw/apic.c b/hw/apic.c index 092c61e..d8c4f7c 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -24,8 +24,6 @@ #include host-utils.h #include kvm.h -#include qemu-kvm.h - //#define DEBUG_APIC /* APIC Local Vector Table */ @@ -951,36 +949,22 @@ static void kvm_kernel_lapic_load_from_user(APICState *s) #endif -void qemu_kvm_load_lapic(CPUState *env) +void kvm_load_lapic(CPUState *env) { #ifdef KVM_CAP_IRQCHIP -if (kvm_enabled() kvm_vcpu_inited(env) kvm_irqchip_in_kernel()) { -kvm_kernel_lapic_load_from_user(env-apic_state); -} -#endif -} - -static void apic_pre_save(void *opaque) -{ -#ifdef KVM_CAP_IRQCHIP -APICState *s = (void *)opaque; - if (kvm_enabled() kvm_irqchip_in_kernel()) { -kvm_kernel_lapic_save_to_user(s); +kvm_kernel_lapic_load_from_user(env-apic_state); } #endif } -static int apic_post_load(void *opaque, int version_id) +void kvm_save_lapic(CPUState *env) { #ifdef KVM_CAP_IRQCHIP -APICState *s = opaque; - if (kvm_enabled() kvm_irqchip_in_kernel()) { -kvm_kernel_lapic_load_from_user(s); +kvm_kernel_lapic_save_to_user(env-apic_state); } #endif -return 0; } /* This function is only used for old state version 1 and 2 */ @@ -1019,9 +1003,6 @@ static int apic_load_old(QEMUFile *f, void *opaque, int version_id) if (version_id = 2) qemu_get_timer(f, s-timer); - -qemu_kvm_load_lapic(s-cpu_env); - return 0; } @@ -1052,9 +1033,7 @@ static const VMStateDescription vmstate_apic = { VMSTATE_INT64(next_time, APICState), VMSTATE_TIMER(timer, APICState), VMSTATE_END_OF_LIST() -}, -.pre_save = apic_pre_save, -.post_load = apic_post_load, +} }; static void apic_reset(void *opaque) @@ -1077,7 +1056,6 @@ static void apic_reset(void *opaque) */ s-lvt[APIC_LVT_LINT0] = 0x700; } -qemu_kvm_load_lapic(s-cpu_env); } static CPUReadMemoryFunc * const apic_mem_read[3] = { @@ -1121,11 +1099,6 @@ int apic_init(CPUState *env) vmstate_register(s-idx, vmstate_apic, s); qemu_register_reset(apic_reset, s); -/* apic_reset must be called before the vcpu threads are initialized and load - * registers, in qemu-kvm. - */ -apic_reset(s); - local_apics[s-idx] = s; return 0; } diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index e5040c9..5cfeb6a 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -984,6 +984,7 @@ void kvm_arch_load_regs(CPUState *env, int level) if (level = KVM_PUT_RESET_STATE) { kvm_arch_load_mpstate(env); +kvm_load_lapic(env); } if (kvm_irqchip_in_kernel()) { /* Avoid deadlock: no user space IRQ will ever clear it. */ @@ -1150,6 +1151,7 @@ void kvm_arch_save_regs(CPUState *env) } } kvm_arch_save_mpstate(env); +kvm_save_lapic(env); kvm_get_vcpu_events(env); } @@ -1223,8 +1225,6 @@ int kvm_arch_init_vcpu(CPUState *cenv) CPUState copy; uint32_t i, j, limit; -qemu_kvm_load_lapic(cenv); - kvm_arch_reset_vcpu(cenv); #ifdef KVM_CPUID_SIGNATURE diff --git a/qemu-kvm.h b/qemu-kvm.h index 4c009c9..9917569 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -864,9 +864,8 @@ static inline void kvm_inject_x86_mce(CPUState *cenv, int bank, int kvm_main_loop(void); int kvm_init_ap(void); int kvm_vcpu_inited(CPUState *env); -void kvm_apic_init(CPUState *env); -/* called from vcpu initialization */ -void qemu_kvm_load_lapic(CPUState *env); +void kvm_save_lapic(CPUState *env); +void kvm_load_lapic(CPUState *env); void kvm_hpet_enable_kpit(void); void kvm_hpet_disable_kpit(void); -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 21/21] qemu-kvm: Bring qemu_init_vcpu back home
There is no need for the this hack anymore, initialization is now robust against reordering as it doesn't try to write the VCPU state on its own. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/pc.c |5 - target-i386/helper.c |2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/hw/pc.c b/hw/pc.c index 3df6195..cd0746c 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -751,11 +751,6 @@ CPUState *pc_new_cpu(const char *cpu_model) } else { qemu_register_reset((QEMUResetHandler*)cpu_reset, env); } - -/* kvm needs this to run after the apic is initialized. Otherwise, - * it can access invalid state and crash. - */ -qemu_init_vcpu(env); return env; } diff --git a/target-i386/helper.c b/target-i386/helper.c index f9d63f6..f83e8cc 100644 --- a/target-i386/helper.c +++ b/target-i386/helper.c @@ -1953,6 +1953,8 @@ CPUX86State *cpu_x86_init(const char *cpu_model) } mce_init(env); +qemu_init_vcpu(env); + return env; } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 18/21] qemu-kvm: Cleanup/fix TSC and PV clock writeback
Drop kvm_load_tsc in favor of level-dependent writeback in kvm_arch_load_regs. KVM's PV clock MSRs fall in the same category and should therefore only be written back on full sync. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- qemu-kvm-x86.c| 19 +-- qemu-kvm.h|4 target-i386/machine.c |5 - 3 files changed, 5 insertions(+), 23 deletions(-) diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c index 23a23eb..e5040c9 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -972,8 +972,11 @@ void kvm_arch_load_regs(CPUState *env, int level) set_msr_entry(msrs[n++], MSR_LSTAR , env-lstar); } #endif -set_msr_entry(msrs[n++], MSR_KVM_SYSTEM_TIME, env-system_time_msr); -set_msr_entry(msrs[n++], MSR_KVM_WALL_CLOCK, env-wall_clock_msr); +if (level == KVM_PUT_FULL_STATE) { +set_msr_entry(msrs[n++], MSR_IA32_TSC, env-tsc); +set_msr_entry(msrs[n++], MSR_KVM_SYSTEM_TIME, env-system_time_msr); +set_msr_entry(msrs[n++], MSR_KVM_WALL_CLOCK, env-wall_clock_msr); +} rc = kvm_set_msrs(env, msrs, n); if (rc == -1) @@ -990,18 +993,6 @@ void kvm_arch_load_regs(CPUState *env, int level) kvm_put_vcpu_events(env, level); } -void kvm_load_tsc(CPUState *env) -{ -int rc; -struct kvm_msr_entry msr; - -set_msr_entry(msr, MSR_IA32_TSC, env-tsc); - -rc = kvm_set_msrs(env, msr, 1); -if (rc == -1) -perror(kvm_set_tsc FAILED.\n); -} - void kvm_arch_save_regs(CPUState *env) { struct kvm_regs regs; diff --git a/qemu-kvm.h b/qemu-kvm.h index ca5c700..4c009c9 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -958,7 +958,6 @@ int handle_tpr_access(void *opaque, CPUState *env, uint64_t rip, #ifdef TARGET_I386 #define qemu_kvm_has_pit_state2() kvm_has_pit_state2(kvm_context) #endif -void kvm_load_tsc(CPUState *env); #else #define kvm_nested 0 #define qemu_kvm_has_gsi_routing() (0) @@ -966,9 +965,6 @@ void kvm_load_tsc(CPUState *env); #define qemu_kvm_has_pit_state2() (0) #endif #define qemu_kvm_cpu_stop(env) do {} while(0) -static inline void kvm_load_tsc(CPUState *env) -{ -} #endif void kvm_mutex_unlock(void); diff --git a/target-i386/machine.c b/target-i386/machine.c index bcc315b..b547e2a 100644 --- a/target-i386/machine.c +++ b/target-i386/machine.c @@ -354,11 +354,6 @@ static int cpu_post_load(void *opaque, int version_id) hw_breakpoint_insert(env, i); tlb_flush(env, 1); - -if (kvm_enabled()) { -kvm_load_tsc(env); -} - return 0; } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 14/21] qemu-kvm: Rework VCPU state writeback API
This grand cleanup drops all reset and vmsave/load related synchronization points in favor of four(!) generic hooks: - cpu_synchronize_all_states in qemu_savevm_state_complete (initial sync from kernel before vmsave) - cpu_synchronize_all_post_init in qemu_loadvm_state (writeback after vmload) - cpu_synchronize_all_post_init in main after machine init - cpu_synchronize_all_post_reset in qemu_system_reset (writeback after system reset) These writeback points + the existing one of VCPU exec after cpu_synchronize_state map on three levels of writeback: - KVM_PUT_ASYNC_STATE (during runtime, other VCPUs continue to run) - KVM_PUT_RESET_STATE (on synchronous system reset, all VCPUs stopped) - KVM_PUT_FULL_STATE (on init or vmload, all VCPUs stopped as well) This level is passed to the arch-specific VCPU state writing function that will decide which concrete substates need to be written. That way, no writer of load, save or reset functions that interact with in-kernel KVM states will ever have to worry about synchronization again. That also means that a lot of reasons for races, segfaults and deadlocks are eliminated. cpu_synchronize_state remains untouched, just as Anthony suggested. We continue to need it before reading or writing of VCPU states that are also tracked by in-kernel KVM subsystems. Consequently, this patch removes many cpu_synchronize_state calls that are now redundant, just like remaining explicit register syncs. It does not touch qemu-kvm's special hooks for mpstate, vcpu_events, or tsc loading. They will be cleaned up by individual patches. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- exec.c| 17 - hw/apic.c |3 --- hw/pc.c |1 - hw/ppc_newworld.c |3 --- hw/ppc_oldworld.c |3 --- hw/s390-virtio.c |1 - kvm-all.c | 19 +-- kvm.h | 22 +- qemu-kvm-ia64.c |2 +- qemu-kvm-x86.c|3 +-- qemu-kvm.c| 16 +--- qemu-kvm.h|2 +- savevm.c |4 sysemu.h |4 target-i386/kvm.c |2 +- target-i386/machine.c | 10 -- target-ia64/machine.c |2 -- target-ppc/kvm.c |2 +- target-ppc/machine.c |4 target-s390x/kvm.c|3 +-- vl.c | 29 + 21 files changed, 90 insertions(+), 62 deletions(-) diff --git a/exec.c b/exec.c index ade09cb..7b35e0f 100644 --- a/exec.c +++ b/exec.c @@ -529,21 +529,6 @@ void cpu_exec_init_all(unsigned long tb_size) #if defined(CPU_SAVE_VERSION) !defined(CONFIG_USER_ONLY) -static void cpu_common_pre_save(void *opaque) -{ -CPUState *env = opaque; - -cpu_synchronize_state(env); -} - -static int cpu_common_pre_load(void *opaque) -{ -CPUState *env = opaque; - -cpu_synchronize_state(env); -return 0; -} - static int cpu_common_post_load(void *opaque, int version_id) { CPUState *env = opaque; @@ -561,8 +546,6 @@ static const VMStateDescription vmstate_cpu_common = { .version_id = 1, .minimum_version_id = 1, .minimum_version_id_old = 1, -.pre_save = cpu_common_pre_save, -.pre_load = cpu_common_pre_load, .post_load = cpu_common_post_load, .fields = (VMStateField []) { VMSTATE_UINT32(halted, CPUState), diff --git a/hw/apic.c b/hw/apic.c index ae805dc..3e03e10 100644 --- a/hw/apic.c +++ b/hw/apic.c @@ -488,7 +488,6 @@ void apic_init_reset(CPUState *env) if (!s) return; -cpu_synchronize_state(env); s-tpr = 0; s-spurious_vec = 0xff; s-log_dest = 0; @@ -1070,8 +1069,6 @@ static void apic_reset(void *opaque) APICState *s = opaque; int bsp; -cpu_synchronize_state(s-cpu_env); - bsp = cpu_is_bsp(s-cpu_env); s-apicbase = 0xfee0 | (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE; diff --git a/hw/pc.c b/hw/pc.c index af6ea8b..6c15a9f 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -744,7 +744,6 @@ CPUState *pc_new_cpu(const char *cpu_model) fprintf(stderr, Unable to find x86 CPU definition\n); exit(1); } -env-kvm_vcpu_dirty = 1; if ((env-cpuid_features CPUID_APIC) || smp_cpus 1) { env-cpuid_apic_id = env-cpu_index; /* APIC reset callback resets cpu */ diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c index a4c714a..9e288bd 100644 --- a/hw/ppc_newworld.c +++ b/hw/ppc_newworld.c @@ -139,9 +139,6 @@ static void ppc_core99_init (ram_addr_t ram_size, envs[i] = env; } -/* Make sure all register sets take effect */ -cpu_synchronize_state(env); - /* allocate RAM */ ram_offset = qemu_ram_alloc(ram_size); cpu_register_physical_memory(0, ram_size, ram_offset); diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c index 7ccc6a1..1aa05ed 100644 --- a/hw/ppc_oldworld.c +++ b/hw/ppc_oldworld.c @@ -164,9
[PATCH v2 13/21] qemu-kvm: Use upstream guest debug code
Code was absolute identical except for previous cleanup in upstream. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c |7 +- kvm.h |4 - qemu-kvm-x86.c| 178 ++-- qemu-kvm.c| 44 - qemu-kvm.h| 37 --- target-i386/kvm.c |2 +- 6 files changed, 11 insertions(+), 261 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 9c921cc..f3cfa2c 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -919,7 +919,9 @@ static void on_vcpu(CPUState *env, void (*func)(void *data), void *data) func(data); #endif } -#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) @@ -938,8 +940,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; @@ -969,7 +969,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 253b45d..740fd1a 100644 --- a/kvm.h +++ b/kvm.h @@ -61,14 +61,12 @@ void kvm_setup_guest_memory(void *start, size_t size); 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); -#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); @@ -101,7 +99,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; @@ -133,7 +130,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..36d805a 100644 --- a/qemu-kvm-x86.c +++ b/qemu-kvm-x86.c @@ -837,6 +837,13 @@ void kvm_arch_load_regs(CPUState *env) kvm_set_regs(env, regs); +/* + * Kernels before 2.6.33 overwrote flags.TF injected via SET_GUEST_DEBUG + * while updating GP regs. Work around this by updating the debug state + * once again. + */ +kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, env-kvm_guest_debug); + memset(fpu, 0, sizeof fpu); fpu.fsw = env-fpus ~(7 11); fpu.fsw |= (env-fpstt 7) 11; @@ -1376,177 +1383,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; - } -
[PATCH v2 09/21] qemu-kvm: Use upstream kvm_pit_in_kernel
Drop private version in favor of recently added upstream service and track it state directly in KVMState. Signed-off-by: Jan Kiszka jan.kis...@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 dac373e..7a7dfa7 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -951,7 +951,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 e7fa605..6cbca97 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -164,13 +164,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 189a5d4..253b45d 100644 --- a/kvm.h +++ b/kvm.h @@ -68,10 +68,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
[PATCH v2 11/21] KVM: Rework of guest debug state writing
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. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c | 12 target-i386/cpu.h |9 - target-i386/kvm.c | 11 +++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 3516f01..9c921cc 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -951,10 +951,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); } @@ -962,12 +958,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/cpu.h b/target-i386/cpu.h index 7d0bbd0..7787fb1 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -21,6 +21,10 @@ #include config.h +#ifdef CONFIG_KVM +#include linux/kvm.h /* for kvm_guest_debug */ +#endif + #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64 #else @@ -718,7 +722,10 @@ typedef struct CPUX86State { uint8_t has_error_code; uint32_t sipi_vector; uint32_t cpuid_kvm_features; - +#if defined(CONFIG_KVM) defined(KVM_CAP_SET_GUEST_DEBUG) +struct kvm_guest_debug kvm_guest_debug; +#endif + /* in order to simplify APIC support, we leave this pointer to the user */ struct APICState *apic_state; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 8743f32..5ac12a8 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -865,6 +865,15 @@ int kvm_arch_put_registers(CPUState *env) if (ret 0) return ret; +/* + * Kernels before 2.6.33 overwrote flags.TF injected via SET_GUEST_DEBUG + * while updating GP regs. Work around this by updating the debug state + * once again. + */ +ret = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, env-kvm_guest_debug); +if (ret 0) +return ret; + ret = kvm_put_fpu(env); if (ret 0) return ret; @@ -1163,6 +1172,8 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg) (len_code[hw_breakpoint[n].len] (18 + n*4)); } } +/* Keep a copy for the writeback workaround in kvm_arch_put_registers */ +memcpy(env-kvm_guest_debug, dbg, sizeof(env-kvm_guest_debug)); } #endif /* KVM_CAP_SET_GUEST_DEBUG */ #endif -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 08/21] qemu-kvm: Use upstream kvm_arch_get_supported_cpuid
It is idential to our version now, so drop the copy. Signed-off-by: Jan Kiszka jan.kis...@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 b5ed744..189a5d4 100644 --- a/kvm.h +++ b/kvm.h @@ -137,11 +137,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 == 0x8001) { - 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 b34b39f..77b8f75 100644 --- a/qemu-kvm.h +++ b/qemu-kvm.h @@ -859,8 +859,6 @@ int kvm_assign_set_msix_entry(kvm_context_t kvm,
Re: [Autotest] [RFC] KVM test: Ship rss.exe and finish.exe binaries with KVM test
Lucas Great!! A nice pill for the windows' pain. On Tue, Feb 2, 2010 at 5:18 PM, Lucas Meneghel Rodrigues l...@redhat.com wrote: Hi folks: We're on an effort of streamlining the KVM test experience, by choosing sane defaults and helper scripts that can overcome the initial barrier with getting the KVM test running. On one of the conversations I've had today, we came up with the idea of shipping the compiled windows programs rss.exe and finish.exe, needed for windows hosts testing. Even though rss.exe and finish.exe can be compiled in a fairly straightforward way using the awesome cross compiling environment with mingw, there are some obvious limitations to it: 1) The cross compiling environment is only available for fedora = 11. No other distros I know have it. And we have to take care of it, otherwise people will not stop complaining about the complexity involved in kvm testing under autotest. 2) Sometimes it might take time for the user to realize he/she has to compile the source code under unattended/ folder, and how to do it. That person would take a couple of failed attempts scratching his/her head thinking what the heck is this deps/finish.exe they're talking about?. Surely documentation can help, and I am looking at making the documentation on how to do it more easily discoverable. That said, shipping the binaries would make the life of those people easier, and anyway the binaries work pretty well across all versions of windows from winxp to win7, they are self contained, with no external dependencies (they all use the standard win32 API). 3) That said we also need a script that can build the entire winutils.iso without making the user to spend way too much time figuring out how to do it. I want to work on such a script on the next days. So, what are your opinions? Should we ship the binaries or pursue a script that can build those for the user as soon as the (yet to be integrated) get_started.py script runs? Remember that the later might mean users of RHEL = 5.X and debian like will be left out in the cold. I am completely in favour of shipping the binaries and the script to make cd.iso This will also help in install setup of windows guest. I know many people complain that getting up with autotest for kvm testing is so complex, which definitely is not(however it appears). This will make windows testing bit more smooth. In my personal experience, I usually keep a fully configured win.img across multiple qemu-kvm versions for running different tests. The freshly installed images after the install test, I usually delete. So my vote is in favour of shipping the binary( and it is not too large). Looking forward hearing your input, Lucas ___ Autotest mailing list autot...@test.kernel.org http://test.kernel.org/cgi-bin/mailman/listinfo/autotest -- Sudhir Kumar -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] kvmppc: guest debug definitions
Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Alex + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. I'd also prefer to see addr be u64. On 32 bit targets we can just use the lower 32 bits only. Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 ++ + arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof (kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) Ah, nice. I have something similar in book3s.c. IIRC it's called kvmppc_ld. I think we should make the semantics identical and declare it as common kvmppc_core function. Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] kvmppc: guest debug definitions
Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 4:57 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Just an invalid instruction which can generate program interrupt... I'm open to it's value btw. Well this definitely doesn't generate a program interrupt. Or at least it shouldn't :-). I just remembered where I've seen an opcode like this before. This is a part of a dump of arch/powerpc/boot/ps3-hvcall.o lv1_get_logical_ppe_id: 0: 7c 08 02 a6 mflrr0 4: 90 01 00 04 stw r0,4(r1) 8: 94 21 ff f0 stwur1,-16(r1) c: 90 61 00 08 stw r3,8(r1) 10: 39 60 00 45 li r11,69 14: 44 00 00 22 sc 1 So as you can see, this is the hypercall instruction for lv1. IIRC beat uses the same. I don't think we want to reuse that opcode for ourselves. Maybe one day someone figures it's a good idea to implement a beat-style ABI in KVM. But IIRC sc can take a lot of values, so we can just take sc 0x1234 or so :-). + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. Yes it's used by ioctl. What's the usually pad size? I don't think there's a default. I just tend to pad it to something reasonable. I guess in this case we can even just extend bp to 128 entries, add a reasonable amount of churn to the debug info and be good: struct kvm_guest_debug_arch { struct { __u64 addr; __u32 type; __u32 pad1; __u64 pad2; } bp[128]; } This should be enough to even leverage performance monitoring stuff later on that would be able to check if r1 == 0x1234 and then stop :-). Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
-Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 ++ + arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof (kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) Ah, nice. I have something similar in book3s.c. IIRC it's called kvmppc_ld. I think we should make the semantics identical and declare it as common kvmppc_core function. Cool. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM-test: Log the output of failed executed command 'pre/post-command'
Sometimes we need the output of failed command 'pre/post-command' when raising error.TestError. Take an example that using post-command to check images of qcow2 format, it will simply tell command failed rather than show '%d errors were found on the image'. Signed-off-by: Yolkfull Chow yz...@redhat.com --- client/tests/kvm/kvm_preprocessing.py |6 -- 1 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py index 4e45c76..53fa2cb 100644 --- a/client/tests/kvm/kvm_preprocessing.py +++ b/client/tests/kvm/kvm_preprocessing.py @@ -148,9 +148,11 @@ def process_command(test, params, env, command, command_timeout, logging.debug, (command) , timeout=command_timeout) if status != 0: -logging.warn(Custom processing command failed: '%s' % command) +logging.warn(Custom processing command failed: '%s'; Output is: %s % +(command, output)) if not command_noncritical: -raise error.TestError(Custom processing command failed) +raise error.TestError(Custom processing command failed: %s % + output) def process(test, params, env, image_func, vm_func): -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/1 net-next] virtio_net: remove send queue
On Tue, Feb 02, 2010 at 01:48:51PM -0800, Shirley Ma wrote: Use detach buffers API in virtio to free unused buffers in send queue when shutting down virtio_net to avoid maintaining skb link list for each transmit packet. Signed-off-by: Shirley Ma x...@us.ibm.com Acked-by: Michael S. Tsirkin m...@redhat.com --- drivers/net/virtio_net.c | 26 -- 1 files changed, 8 insertions(+), 18 deletions(-) diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 9d8984a..8069c08 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -56,9 +56,6 @@ struct virtnet_info /* Host will merge rx buffers for big packets (shake it! shake it!) */ bool mergeable_rx_bufs; - /* Send queue. */ - struct sk_buff_head send; - /* Work struct for refilling if we run low on memory. */ struct delayed_work refill; @@ -505,7 +502,6 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi) while ((skb = vi-svq-vq_ops-get_buf(vi-svq, len)) != NULL) { pr_debug(Sent skb %p\n, skb); - __skb_unlink(skb, vi-send); vi-dev-stats.tx_bytes += skb-len; vi-dev-stats.tx_packets++; tot_sgs += skb_vnet_hdr(skb)-num_sg; @@ -588,15 +584,6 @@ again: } vi-svq-vq_ops-kick(vi-svq); - /* - * Put new one in send queue. You'd expect we'd need this before - * xmit_skb calls add_buf(), since the callback can be triggered - * immediately after that. But since the callback just triggers - * another call back here, normal network xmit locking prevents the - * race. - */ - __skb_queue_head(vi-send, skb); - /* Don't wait up for transmitted skbs to be freed. */ skb_orphan(skb); nf_reset(skb); @@ -977,9 +964,6 @@ static int virtnet_probe(struct virtio_device *vdev) dev-features |= NETIF_F_HW_VLAN_FILTER; } - /* Initialize our empty send queue. */ - skb_queue_head_init(vi-send); - err = register_netdev(dev); if (err) { pr_debug(virtio_net: registering device failed\n); @@ -1016,6 +1000,12 @@ static void free_unused_bufs(struct virtnet_info *vi) { void *buf; while (1) { + buf = vi-svq-vq_ops-detach_unused_buf(vi-svq); + if (!buf) + break; + dev_kfree_skb(buf); + } + while (1) { buf = vi-rvq-vq_ops-detach_unused_buf(vi-rvq); if (!buf) break; @@ -1035,11 +1025,11 @@ static void __devexit virtnet_remove(struct virtio_device *vdev) /* Stop all the virtqueues. */ vdev-config-reset(vdev); - /* Free our skbs in send queue, if any. */ - __skb_queue_purge(vi-send); unregister_netdev(vi-dev); cancel_delayed_work_sync(vi-refill); + + /* Free unused buffers in both send and recv, if any. */ free_unused_bufs(vi); vdev-config-del_vqs(vi-vdev); -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. MSRDE is set to 0 by critical class interrupts unless Category E.ED is supported, by Debug interrupts, and by Machine Check interrupts, and is left unchanged by all other interrupts. Great. So when single stepping is enabled, you jump into the guest, get an itlb miss, get out, still have DE set, get in KVM's own DE handler and can process things from there. Could you check if the debug instruction was on PR=0? If so, you can just rfi and be good, right? Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/8] KVM: Activate fpu on clts
On Tue, Feb 02, 2010 at 09:16:44AM +0100, Paolo Bonzini wrote: On 01/21/2010 02:31 PM, Avi Kivity wrote: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index feca59f..09207ba 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3266,6 +3266,7 @@ int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address) int emulate_clts(struct kvm_vcpu *vcpu) { kvm_x86_ops-set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS)); +kvm_x86_ops-fpu_activate(vcpu); return X86EMUL_CONTINUE; } Can this code be reached if CLTS is executed in real mode? That would cause a NULL-pointer access on VMX. We should assume that any part of emulator can be reached from a guest and do check accordingly. -- Gleb. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/4] kvmppc/booke: guest debug support
Liu Yu wrote: According to user's gdb command, we set the corresponding debug control bits in shadow. Signed-off-by: Liu Yu yu.liu-kzfg59tc24xl57midrc...@public.gmane.org --- arch/powerpc/include/asm/kvm_ppc.h |3 + arch/powerpc/kvm/booke.c | 93 ++-- arch/powerpc/kvm/e500.c|8 --- arch/powerpc/kvm/powerpc.c |2 +- 4 files changed, 93 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index e264282..8918aac 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -94,6 +94,9 @@ extern int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu, extern int kvmppc_core_emulate_mtspr(struct kvm_vcpu *vcpu, int sprn, int rs); extern int kvmppc_core_emulate_mfspr(struct kvm_vcpu *vcpu, int sprn, int rt); +extern int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu, + struct kvm_guest_debug *dbg); + extern int kvmppc_booke_init(void); extern void kvmppc_booke_exit(void); diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index 4d686cc..ec2722d 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -267,6 +267,16 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, break; } + if (unlikely(vcpu-guest_debug KVM_GUESTDBG_ENABLE) This should better check for KVM_GUESTDBG_USE_SW_BP. + (vcpu-arch.last_inst == KVM_INST_GUESTGDB)) { + run-exit_reason = KVM_EXIT_DEBUG; + run-debug.arch.pc = vcpu-arch.pc; + run-debug.arch.exception = exit_nr; + kvmppc_account_exit(vcpu, DEBUG_EXITS); + r = RESUME_HOST; + break; + } + er = kvmppc_emulate_instruction(run, vcpu); switch (er) { case EMULATE_DONE: @@ -293,6 +303,12 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, default: BUG(); } + + if (unlikely(vcpu-guest_debug KVM_GUESTDBG_ENABLE) + (vcpu-guest_debug KVM_GUESTDBG_SINGLESTEP)) { Checking for KVM_GUESTDBG_ENABLE is redundant as you enforce guest_debug = 0 in kvmppc_core_set_guest_debug if KVM_GUESTDBG_ENABLE is not set. + run-exit_reason = KVM_EXIT_DEBUG; + r = RESUME_HOST; + } break; case BOOKE_INTERRUPT_FP_UNAVAIL: @@ -421,12 +437,27 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, u32 dbsr; vcpu-arch.pc = mfspr(SPRN_CSRR0); - - /* clear IAC events in DBSR register */ dbsr = mfspr(SPRN_DBSR); - dbsr = DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4; - mtspr(SPRN_DBSR, dbsr); + run-debug.arch.pc = vcpu-arch.pc; + run-debug.arch.status = 0; + + if (dbsr (DBSR_IAC1 | DBSR_IAC2 | DBSR_IAC3 | DBSR_IAC4)) { + run-debug.arch.status |= KVMPPC_DEBUG_BREAKPOINT; + } else { + if (dbsr (DBSR_DAC1W | DBSR_DAC2W)) + run-debug.arch.status |= KVMPPC_DEBUG_WATCH_WRITE; + else if (dbsr (DBSR_DAC1R | DBSR_DAC2R)) + run-debug.arch.status |= KVMPPC_DEBUG_WATCH_READ; + if (dbsr (DBSR_DAC1R | DBSR_DAC1W)) + run-debug.arch.pc = vcpu-arch.shadow_dbg_reg.dac1; + else if (dbsr (DBSR_DAC2R | DBSR_DAC2W)) + run-debug.arch.pc = vcpu-arch.shadow_dbg_reg.dac2; + } + /* clear events in DBSR register */ + mtspr(SPRN_DBSR, ~0); + + run-debug.arch.exception = exit_nr; run-exit_reason = KVM_EXIT_DEBUG; kvmppc_account_exit(vcpu, DEBUG_EXITS); r = RESUME_HOST; @@ -560,6 +591,60 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log) return -ENOTSUPP; } +int kvmppc_core_set_guest_debug(struct kvm_vcpu *vcpu, +struct kvm_guest_debug *dbg) +{ + if (!(dbg-control KVM_GUESTDBG_ENABLE)) { + vcpu-guest_debug = 0; + return 0; + } + + vcpu-guest_debug = dbg-control; + vcpu-arch.shadow_dbg_reg.dbcr0 = 0; + + if (vcpu-guest_debug KVM_GUESTDBG_SINGLESTEP) + vcpu-arch.shadow_dbg_reg.dbcr0 |= DBCR0_IDM | DBCR0_IC; + + if (vcpu-guest_debug KVM_GUESTDBG_USE_HW_BP) { + struct kvmppc_debug_reg *gdbgr = (vcpu-arch.shadow_dbg_reg); + int n, b = 0, w
RE: [PATCH 1/4] kvmppc: guest debug definitions
-Original Message- From: Alexander Graf [mailto:ag...@suse.de] Sent: Wednesday, February 03, 2010 5:51 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 4:57 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Just an invalid instruction which can generate program interrupt... I'm open to it's value btw. Well this definitely doesn't generate a program interrupt. Or at least it shouldn't :-). I just remembered where I've seen an opcode like this before. This is a part of a dump of arch/powerpc/boot/ps3-hvcall.o lv1_get_logical_ppe_id: 0: 7c 08 02 a6 mflrr0 4: 90 01 00 04 stw r0,4(r1) 8: 94 21 ff f0 stwur1,-16(r1) c: 90 61 00 08 stw r3,8(r1) 10: 39 60 00 45 li r11,69 14: 44 00 00 22 sc 1 So as you can see, this is the hypercall instruction for lv1. IIRC beat uses the same. I don't think we want to reuse that opcode for ourselves. Maybe one day someone figures it's a good idea to implement a beat-style ABI in KVM. But IIRC sc can take a lot of values, so we can just take sc 0x1234 or so :-). + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. Yes it's used by ioctl. What's the usually pad size? I don't think there's a default. I just tend to pad it to something reasonable. I guess in this case we can even just extend bp to 128 entries, add a reasonable amount of churn to the debug info and be good: struct kvm_guest_debug_arch { struct { __u64 addr; __u32 type; __u32 pad1; __u64 pad2; } bp[128]; } Software breakpoint is maintained by qemu. Here it's only used by hardware breakpoint/watchpoint Is 128 much too large? -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
-Original Message- From: Alexander Graf [mailto:ag...@suse.de] Sent: Wednesday, February 03, 2010 6:14 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. MSRDE is set to 0 by critical class interrupts unless Category E.ED is supported, by Debug interrupts, and by Machine Check interrupts, and is left unchanged by all other interrupts. Great. So when single stepping is enabled, you jump into the guest, get an itlb miss, get out, still have DE set, get in KVM's own DE handler and can process things from there. Could you check if the debug instruction was on PR=0? If so, you can just rfi and be good, right? Hr? The moment we found this happen we've already saved the guest and loaded host on exit path Rfi will make exit path again which means save guest again. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/6] KVM test: Removing qemu/qemu-kvm variants from tests
On Wed, 2010-02-03 at 06:05 -0500, Michael Goldish wrote: - Lucas Meneghel Rodrigues l...@redhat.com wrote: The idea of having a qemu/qemu-kvm variants block turned out to be a bad idea, since we are never meant to run them in combination. So let's roll back this change and give some examples on tests.cfg. Also, cleaned up tests.cfg.sample, and introduced Fedora 12 as the default host, as it is the latest Fedora upstream. Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com --- client/tests/kvm/tests.cfg.sample | 48 ++-- client/tests/kvm/tests_base.cfg.sample |8 - 2 files changed, 9 insertions(+), 47 deletions(-) diff --git a/client/tests/kvm/tests.cfg.sample b/client/tests/kvm/tests.cfg.sample index bde4efa..c478ba2 100644 --- a/client/tests/kvm/tests.cfg.sample +++ b/client/tests/kvm/tests.cfg.sample @@ -20,66 +20,36 @@ include cdkeys.cfg #cdrom.* ?= /tmp/kvm_autotest_root/ #steps ?= /tmp/kvm_autotest_root/ -# You will notice that in all test definition blocks we have 'only qemu-kvm' -# set. This means that qemu-kvm command line syntax will be used. If you -# intend to test qemu upstream, you'll have to change that to 'only qemu'. variants: - @full: -only qemu-kvm -- @sample1: -only qemu-kvm -only no_pci_assignable -only Fedora Windows -- @sample2: +- @fc12_qemu: only qemu-kvm Didn't you mean to remove this line? Yes, will fix both on a later version of the patch. It occurred to me that it is a good idea to ship more pre-canned test sets, which contain windows and some other test scenarios. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
Liu Yu-B13201 wrote: -Original Message- From: Alexander Graf [mailto:ag...@suse.de] Sent: Wednesday, February 03, 2010 6:14 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-...@vger.kernel.org; kvm@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. MSRDE is set to 0 by critical class interrupts unless Category E.ED is supported, by Debug interrupts, and by Machine Check interrupts, and is left unchanged by all other interrupts. Great. So when single stepping is enabled, you jump into the guest, get an itlb miss, get out, still have DE set, get in KVM's own DE handler and can process things from there. Could you check if the debug instruction was on PR=0? If so, you can just rfi and be good, right? Hr? The moment we found this happen we've already saved the guest and loaded host on exit path Rfi will make exit path again which means save guest again. Well the guest saving code is in our hands. So we can just modify the debug interrupt handler in booke_interrupts.S to check for PR=0 first thing and then decide whether to save to guest state or return to the host kernel. I think that'd make it a lot cleaner. Alex -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[KVM-AUTOTEST PATCH 1/1] KVM test: kvm_vm.py: shorten VM.destroy()
Call self.pci_assignable.release_devs() in the finally block. Signed-off-by: Michael Goldish mgold...@redhat.com --- client/tests/kvm/kvm_vm.py | 11 ++- 1 files changed, 2 insertions(+), 9 deletions(-) diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py index 6731927..db903a0 100755 --- a/client/tests/kvm/kvm_vm.py +++ b/client/tests/kvm/kvm_vm.py @@ -598,8 +598,6 @@ class VM: # Is it already dead? if self.is_dead(): logging.debug(VM is already down) -if self.pci_assignable: -self.pci_assignable.release_devs() return logging.debug(Destroying VM with PID %d... % @@ -620,9 +618,6 @@ class VM: return finally: session.close() -if self.pci_assignable: -self.pci_assignable.release_devs() - # Try to destroy with a monitor command logging.debug(Trying to kill VM with monitor command...) @@ -632,8 +627,6 @@ class VM: # Wait for the VM to be really dead if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5): logging.debug(VM is down) -if self.pci_assignable: -self.pci_assignable.release_devs() return # If the VM isn't dead yet... @@ -643,13 +636,13 @@ class VM: # Wait for the VM to be really dead if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5): logging.debug(VM is down) -if self.pci_assignable: -self.pci_assignable.release_devs() return logging.error(Process %s is a zombie! % self.process.get_pid()) finally: +if self.pci_assignable: +self.pci_assignable.release_devs() if self.process: self.process.close() try: -- 1.5.4.1 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Odd disk speed limit with KVM when using encrypted disks and striped LVM
Hi! I'm experimenting with KVM on my modest home server, and I ran into a peculiar issue that I can't explain, so I'm now looking for some insight. The problem I see is that raw sequential disk read speed from within a guest is somehow limited. I did some measurements and I don't really understand the result. My setup is as follows: Two SATA HDDs are set up with full disk encryption (LUKS) and used as physical volumes in an LVM volume group. On this VG I create a striped LV, and when measuring raw read speed on this I get about 113MB/s. The decryption is handled by two threads, each consuming about 50% of one CPU core. The raw disk speed for one disk is around 60-70MB/s, so this is as expected. When I instead connect these encrypted devices to a virtual machine using virtio, and doing the same measurements, I get the same raw disk speed when measuring only one disk, but when I measure on the striped volume, I only get about half the speed I expect. I can still see that the two kcryptd processes are running, but they now only consume about 25% CPU time each, and nothing else seem to be maxed out. The 'dd' process on the guest is consuming 9% CPU, and the kvm process on the host is using about 30% of one core. All timing is measured like this: time dd /dev/vgfs/striped bs=256k count=1 /dev/null I'd be grateful for any insight, since it might help me understand other bottlenecks I might stumble upon in the future. This disk speed issue is not much of a problem really, but I think it's odd. Just tell me if you want more details about the case. // Anders -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[KVM-AUTOTEST PATCH 1/1] KVM test: make sure the boot test does what it's supposed to
Currently the boot test starts the VM only if it isn't already running. If the VM is running, the boot test is essentially a login test. 'restart_vm = yes' will make the preprocessor restart the VM anyway. Signed-off-by: Michael Goldish mgold...@redhat.com --- client/tests/kvm/tests_base.cfg.sample |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index 87aeb67..6eeecb9 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -73,6 +73,7 @@ variants: - boot: install setup unattended_install type = boot +restart_vm = yes kill_vm_on_error = yes - reboot: install setup unattended_install -- 1.5.4.1 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 6/6] KVM test: Add a get_started.py script
- Lucas Meneghel Rodrigues l...@redhat.com wrote: In order to make it easier to get started with KVM testing, add a script that helps with setting up directories, paths and iso files for the default test configuration (Fedora 12 guest install, boot test, shutdown). Once the first idea of how things work is formed, one may start to tinker with configuration files. Added pointers to the online documentation. Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com --- client/tests/kvm/README | 19 +++- client/tests/kvm/get_started.py | 103 +++ 2 files changed, 121 insertions(+), 1 deletions(-) create mode 100755 client/tests/kvm/get_started.py diff --git a/client/tests/kvm/README b/client/tests/kvm/README index 88d2c15..628f3d9 100644 --- a/client/tests/kvm/README +++ b/client/tests/kvm/README @@ -1,3 +1,20 @@ -In order to get started, please refer to the online documentation: +For the impatient: + +Execute the get_started.py script located on this directory, +that will guide you through setting up the default kvm test +scenario: + + * Guest install with Fedora 12 + * Boot, reboot and shutdown test + +The script will help you to create all the directories, and +even get the OS iso in case you don't have it yet. + +For the not so impatient: + +You are *strongly* advised to read the online docs: http://www.linux-kvm.org/page/KVM-Autotest/Client_Install + +So you can have a better idea of how the test is organized +and how it works. diff --git a/client/tests/kvm/get_started.py b/client/tests/kvm/get_started.py new file mode 100755 index 000..51d98f0 --- /dev/null +++ b/client/tests/kvm/get_started.py @@ -0,0 +1,103 @@ +#!/usr/bin/python + +Program to help setup kvm test environment + +...@copyright: Red Hat 2010 + + +import os, sys, optparse, logging, shutil +import common, kvm_utils +from autotest_lib.client.common_lib import logging_manager +from autotest_lib.client.bin import utils, os_dep + + +if __name__ == __main__: +logging_manager.configure_logging(kvm_utils.KvmLoggingConfig(), + verbose=True) +logging.info(KVM test config helper) + +logging.info(1 - Verifying directories (check if the directory structure + expected by the default test config is there)) +base_dir = /tmp/kvm_autotest_root +sub_dir_list = [images, isos, steps_data] +for sub_dir in sub_dir_list: +sub_dir_path = os.path.join(base_dir, sub_dir) +if not os.path.isdir(sub_dir_path): +logging.debug(Creating %s, sub_dir_path) +os.makedirs(sub_dir_path) +else: +logging.debug(Dir %s exists, not creating % + sub_dir_path) +logging.info(Do you want to setup NFS mounts for some of those + dirs? (y/n)) +setup_nfs = raw_input() +if setup_nfs == 'y': +logging.info(Exiting the script so you can setup the NFS mounts. + When you are done, re-run this script.) +sys.exit(0) + +logging.info(2 - Creating config files from samples (copy the default + config samples to actual config files)) +kvm_test_dir = os.path.dirname(sys.modules[__name__].__file__) +kvm_test_dir = os.path.abspath(kvm_test_dir) +config_file_list = [address_pools.cfg, build.cfg, cdkeys.cfg, +tests_base.cfg, tests.cfg] +for config_file in config_file_list: +src_file = os.path.join(kvm_test_dir, %s.sample % config_file) +dst_file = os.path.join(kvm_test_dir, config_file) +if not os.path.isfile(dst_file): +logging.debug(Creating config file %s from sample, dst_file) +shutil.copyfile(src_file, dst_file) +else: +logging.debug(Config file %s exists, not touching % dst_file) + +logging.info(3 - Verifying iso (make sure we have the OS iso needed for + the default test set)) +base_iso_name = Fedora-12-x86_64-DVD.iso +fedora_dir = pub/fedora/linux/releases/12/Fedora/x86_64/iso +url = os.path.join(http://download.fedoraproject.org/;, fedora_dir, + base_iso_name) +md5sum = 6dd31e292cc2eb1140544e9b1ba61c56 +iso_dir = os.path.join(base_dir, 'images', 'linux') +if not iso_dir: +os.makedirs(iso_dir) +iso_path = os.path.join(iso_dir, base_iso_name) +if not os.path.isfile(iso_path) or ( + kvm_utils.hash_file(iso_path, method=md5) != md5sum): +logging.warning(%s not found or corrupted, iso_path) +logging.warning(Would you like to download it? (y/n)) +iso_download = raw_input() +if iso_download == 'y': +kvm_utils.unmap_url_cache(iso_dir, url, md5sum) +else: +logging.warning(Missing file %s.
Re: [Autotest] [PATCH 3/6] KVM test: Make sure reset and shutdown are the last ones
- Lucas Meneghel Rodrigues l...@redhat.com wrote: system_reset, system_powerdown and shutdown *must* be the last ones defined, since the effect of such tests can leave the VM on a bad state. Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com --- client/tests/kvm/tests_base.cfg.sample | 35 +-- 1 files changed, 19 insertions(+), 16 deletions(-) diff --git a/client/tests/kvm/tests_base.cfg.sample b/client/tests/kvm/tests_base.cfg.sample index 8a7a13d..fdd04cb 100644 --- a/client/tests/kvm/tests_base.cfg.sample +++ b/client/tests/kvm/tests_base.cfg.sample @@ -236,6 +236,24 @@ variants: - fmt_raw: image_format_stg = raw +- vlan_tag: install setup unattended_install +type = vlan_tag +# subnet should not be used by host +subnet = 192.168.123 +vlans = 10 20 +nic_mode = tap +vms += vm2 +extra_params_vm1 += -snapshot +extra_params_vm2 += -snapshot +kill_vm_gracefully_vm2 = no +address_index_vm2 = 1 + +- physical_resources_check: install setup unattended_install +type = physical_resources_check +catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}' + +# system_reset, system_powerdown and shutdown *must* be the last ones +# defined, since the effect of such tests can leave the VM on a bad state. I think the order should be system_powerdown, system_reset, shutdown. We should minimize the number of tests running after system_reset. - system_reset: install setup unattended_install type = boot reboot_method = system_reset @@ -254,22 +272,7 @@ variants: shutdown_method = shell kill_vm = yes kill_vm_gracefully = no - -- vlan_tag: install setup unattended_install -type = vlan_tag -# subnet should not be used by host -subnet = 192.168.123 -vlans = 10 20 -nic_mode = tap -vms += vm2 -extra_params_vm1 += -snapshot -extra_params_vm2 += -snapshot -kill_vm_gracefully_vm2 = no -address_index_vm2 = 1 - -- physical_resources_check: install setup unattended_install -type = physical_resources_check -catch_uuid_cmd = dmidecode | awk -F: '/UUID/ {print $2}' +# Do not define test variants below shutdown # NICs variants: -- 1.6.6 ___ Autotest mailing list autot...@test.kernel.org http://test.kernel.org/cgi-bin/mailman/listinfo/autotest -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: -smp =2 + -no-kvm-irqchip broken
On Tue, Feb 02, 2010 at 07:56:42PM +0100, Jan Kiszka wrote: Jan Kiszka wrote: Gleb Natapov wrote: On Tue, Feb 02, 2010 at 05:41:03PM +0100, Jan Kiszka wrote: Gleb Natapov wrote: On Tue, Feb 02, 2010 at 05:29:53PM +0100, Jan Kiszka wrote: Hi, notice while testing v2 of my vcpu state series: Starting SMP guests like Linux or Vista without in-kernel irqchip and with more than one CPU make them lock up during boot (Vista) or spit out messages like udevd[112] trap invalid opcode ip:7fc434630950 sp:7fff3cd3fcb8 error:0 in libc-2.9.so[7fc4345b2000+14f000] Looks like interrupt is injected as exception. Can you try to bisect? Already started (as low prio background task), first looking for a good version. If you know a recent one, I'm a taker. Nope, didn't try no kernel irqchip for a long time. Kernel plays the key role here, either kvm-kmod or actually the kvm module: kvm-kmod-2.6.31.6 works, the 2.6.32 series and later do not. Digging deeper... I take this back: It works for Linux guests, but Vista crashes also with old kvm-kmod. So there is no way around real debugging. Upstream qemu-kvm/kvm works for me. Boot linux with -smp 2 and windows2008-32 with -smp 4. -- Gleb. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Autotest] [RFC] KVM test: Ship rss.exe and finish.exe binaries with KVM test
- Uri Lublin u...@redhat.com wrote: On 02/02/2010 01:48 PM, Lucas Meneghel Rodrigues wrote: Hi folks: We're on an effort of streamlining the KVM test experience, by choosing sane defaults and helper scripts that can overcome the initial barrier with getting the KVM test running. On one of the conversations I've had today, we came up with the idea of shipping the compiled windows programs rss.exe and finish.exe, needed for windows hosts testing. Even though rss.exe and finish.exe can be compiled in a fairly straightforward way using the awesome cross compiling environment with mingw, there are some obvious limitations to it: 1) The cross compiling environment is only available for fedora= 11. No other distros I know have it. 2) Sometimes it might take time for the user to realize he/she has to compile the source code under unattended/ folder, and how to do it. That person would take a couple of failed attempts scratching his/her head thinking what the heck is this deps/finish.exe they're talking about?. Surely documentation can help, and I am looking at making the documentation on how to do it more easily discoverable. That said, shipping the binaries would make the life of those people easier, and anyway the binaries work pretty well across all versions of windows from winxp to win7, they are self contained, with no external dependencies (they all use the standard win32 API). 3) That said we also need a script that can build the entire winutils.iso without making the user to spend way too much time figuring out how to do it. I want to work on such a script on the next days. So, what are your opinions? Should we ship the binaries or pursue a script that can build those for the user as soon as the (yet to be integrated) get_started.py script runs? Remember that the later might mean users of RHEL= 5.X and debian like will be left out in the cold. 4) Another option is to make winutils.iso available (somewhere on the web), and download it in get_started.py (similar to other iso images used by kvm test). But isn't there a legal problem with that? winutils.iso contains VLC media player (for the timedrift test). If there's no legal problem, this sounds like the best option to me. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH AUTOTEST] kvm: timedrift test: fix typo (host_delta_t)
- Uri Lublin u...@redhat.com wrote: Signed-off-by: Uri Lublin u...@redhat.com --- client/tests/kvm/tests/timedrift.py |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/client/tests/kvm/tests/timedrift.py b/client/tests/kvm/tests/timedrift.py index b3e8770..06f6a70 100644 --- a/client/tests/kvm/tests/timedrift.py +++ b/client/tests/kvm/tests/timedrift.py @@ -160,7 +160,7 @@ def run_timedrift(test, params, env): # Report results host_delta_total = ht2 - ht0 guest_delta_total = gt2 - gt0 -drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta +drift_total = 100.0 * (host_delta_total - guest_delta_total) / host_delta_total This isn't a typo. delta_total is the load duration (e.g. 1 min of video decoding) + rest duration (e.g. 20 secs of idleness). I think the load drift and the total drift should be divided by the same delta, in order to determine the amount of drift corrected during idleness. If you divide the total drift by delta_total (instead of delta) you give a false impression that more drift was corrected than really was. I'm not sure I'm making my point clearly so here's an example: Let's assume: - The load duration is 30s; - the idle duration is 30s; - the drift was 10s; - the drift was not corrected at all during idleness -- so after the idle period the drift remained 10s. Then: - The load drift is 33.3% (10/30); - if you divide by delta, the total drift is still 33.3% (10/30); - if you divide by delta_total, the total drift is 16.6% (10/60). So dividing by delta_total gives the impression that some drift was corrected, when in fact none was. logging.info(Total host duration including rest: %.2f % host_delta_total) logging.info(Total guest duration including rest: %.2f % guest_delta_total) logging.info(Total drift after rest: %.2f%% % drift_total) -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] audio streaming from usb devices
I have streaming audio devices working within qemu-kvm. This is a port of the changes to qemu. Streaming audio generates a series of isochronous requests that are repetitive and time sensitive. The URBs need to be submitted in consecutive USB frames and responses need to be handled in a timely manner. Summary of the changes for isochronous requests: 1. The initial 'valid' value is increased to 32. It needs to be higher than its current value of 10 since the host adds a 10 frame delay to the scheduling of the first request; if valid is set to 10 the first isochronous request times out and qemu cancels it. 32 was chosen as a nice round number, and it is used in the path where a TD-async pairing already exists. 2. The token field in the TD is *not* unique for isochronous requests, so it is not a good choice for finding a matching async request. The buffer (where to write the guest data) is unique, so use that value instead. 3. TD's for isochronous request need to be completed in the async completion handler so that data is pushed to the guest as soon as it is available. The uhci code currently attempts to process complete isochronous TDs the next time the UHCI frame with the request is processed. The results in lost data since the async requests will have long since timed out based on the valid parameter. Increasing the valid value is not acceptable as it introduces a 1+ second delay in the data getting pushed to the guest. 4. The frame timer needs to be run on 1 msec intervals. Currently, the expire time for the processing the next frame is computed after the processing of each frame. This regularly causes the scheduling of frames to shift in time. When this happens the periodic scheduling of the requests is broken and the subsequent request is seen as a new request by the host resulting in a 10 msec delay (first isochronous request is scheduled for 10 frames from when the URB is submitted). [ For what's worth a small change is needed to the guest driver to have more outstanding URBs (at least 4 URBs with 5 packets per URB).] Signed-off-by: David Ahern daah...@cisco.com diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c index fdbb4d1..19b4ce6 100644 --- a/hw/usb-uhci.c +++ b/hw/usb-uhci.c @@ -112,6 +112,7 @@ typedef struct UHCIAsync { uint32_t td; uint32_t token; int8_tvalid; +uint8_t isoc; uint8_t done; uint8_t buffer[2048]; } UHCIAsync; @@ -131,6 +132,7 @@ typedef struct UHCIState { uint32_t fl_base_addr; /* frame list base address */ uint8_t sof_timing; uint8_t status2; /* bit 0 and 1 are used to generate UHCI_STS_USBINT */ +int64_t expire_time; QEMUTimer *frame_timer; UHCIPort ports[NB_PORTS]; @@ -164,6 +166,7 @@ static UHCIAsync *uhci_async_alloc(UHCIState *s) async-td= 0; async-token = 0; async-done = 0; +async-isoc = 0; async-next = NULL; return async; @@ -762,13 +765,25 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in { UHCIAsync *async; int len = 0, max_len; -uint8_t pid; +uint8_t pid, isoc; +uint32_t token; /* Is active ? */ if (!(td-ctrl TD_CTRL_ACTIVE)) return 1; -async = uhci_async_find_td(s, addr, td-token); +/* token field is not unique for isochronous requests, + * so use the destination buffer + */ +if (td-ctrl TD_CTRL_IOS) { +token = td-buffer; +isoc = 1; +} else { +token = td-token; +isoc = 0; +} + +async = uhci_async_find_td(s, addr, token); if (async) { /* Already submitted */ async-valid = 32; @@ -785,9 +800,13 @@ static int uhci_handle_td(UHCIState *s, uint32_t addr, UHCI_TD *td, uint32_t *in if (!async) return 1; -async-valid = 10; +/* valid needs to be large enough to handle 10 frame delay + * for initial isochronous requests + */ +async-valid = 32; async-td= addr; -async-token = td-token; +async-token = token; +async-isoc = isoc; max_len = ((td-token 21) + 1) 0x7ff; pid = td-token 0xff; @@ -841,9 +860,31 @@ static void uhci_async_complete(USBPacket *packet, void *opaque) dprintf(uhci: async complete. td 0x%x token 0x%x\n, async-td, async-token); -async-done = 1; +if (async-isoc) { +UHCI_TD td; +uint32_t link = async-td; +uint32_t int_mask = 0, val; +int len; + +cpu_physical_memory_read(link ~0xf, (uint8_t *) td, sizeof(td)); +le32_to_cpus(td.link); +le32_to_cpus(td.ctrl); +le32_to_cpus(td.token); +le32_to_cpus(td.buffer); + +uhci_async_unlink(s, async); +len = uhci_complete_td(s, td, async, int_mask); +s-pending_int_mask |= int_mask; -uhci_process_frame(s); +/* update the status bits of the TD */ +val = cpu_to_le32(td.ctrl); +cpu_physical_memory_write((link ~0xf) + 4, +
[PATCH] segfault due to buffer overrun in usb-serial
This fixes a segfault due to buffer overrun in the usb-serial device. The memcpy was incrementing the start location by recv_used yet, the computation of first_size (how much to write at the end of the buffer before wrapping to the front) was not accounting for it. This causes the next element after the receive buffer (recv_ptr) to get overwritten with random data. Signed-off-by: David Ahern daah...@cisco.com diff --git a/hw/usb-serial.c b/hw/usb-serial.c index 37293ea..c3f3401 100644 --- a/hw/usb-serial.c +++ b/hw/usb-serial.c @@ -497,12 +497,28 @@ static int usb_serial_can_read(void *opaque) static void usb_serial_read(void *opaque, const uint8_t *buf, int size) { USBSerialState *s = opaque; -int first_size = RECV_BUF - s-recv_ptr; -if (first_size size) -first_size = size; -memcpy(s-recv_buf + s-recv_ptr + s-recv_used, buf, first_size); -if (size first_size) -memcpy(s-recv_buf, buf + first_size, size - first_size); +int first_size, start; + +/* room in the buffer? */ +if (size (RECV_BUF - s-recv_used)) +size = RECV_BUF - s-recv_used; + +start = s-recv_ptr + s-recv_used; +if (start RECV_BUF) { +/* copy data to end of buffer */ +first_size = RECV_BUF - start; +if (first_size size) +first_size = size; + +memcpy(s-recv_buf + start, buf, first_size); + +/* wrap around to front if needed */ +if (size first_size) +memcpy(s-recv_buf, buf + first_size, size - first_size); +} else { +start -= RECV_BUF; +memcpy(s-recv_buf + start, buf, size); +} s-recv_used += size; } -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] add close callback for tty-based char device
Add a tty close callback. Right now if a guest device that is connected to a tty-based chardev in the host is removed, the tty is not closed. With this patch it is closed. Example use case is connecting an emulated USB serial cable in the guest to tty0 of the host using the monitor command: usb_add serial::/dev/tty0 and then removing the device with: usb_del serial::/dev/tty0 Signed-off-by: David Ahern daah...@cisco.com diff --git a/qemu-char.c b/qemu-char.c index 800ee6c..ecd84ec 100644 --- a/qemu-char.c +++ b/qemu-char.c @@ -1173,6 +1173,20 @@ static int tty_serial_ioctl(CharDriverState *chr, int cmd return 0; } +static void qemu_chr_close_tty(CharDriverState *chr) +{ +FDCharDriver *s = chr-opaque; +int fd = -1; + +if (s) +fd = s-fd_in; + +fd_chr_close(chr); + +if (fd = 0) +close(fd); +} + static CharDriverState *qemu_chr_open_tty(QemuOpts *opts) { const char *filename = qemu_opt_get(opts, path); @@ -1187,6 +1201,7 @@ static CharDriverState *qemu_chr_open_tty(QemuOpts *opts) return NULL; } chr-chr_ioctl = tty_serial_ioctl; +chr-chr_close = qemu_chr_close_tty; return chr; } #else /* ! __linux__ ! __sun__ */ -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/21] qemu-kvm: Hook cleanups and extended use of upstream code
On Wed, Feb 03, 2010 at 09:53:25AM +0100, Jan Kiszka wrote: This version addresses the feedback on v2, namely: - assert(vm stopped || current thread == env-thread) on low-level load/save registers - fixed mpstate initialization Yet untested is -no-kvm-irqchip with smp due to some bug in unpatched qemu-kvm or the kernel modules. Still investigating. Don't recall it ever working properly. Guess that IPI emulation with signals is problematic. Pull URL is still git://git.kiszka.org/qemu-kvm.git queues/vcpu-state PS: The corresponding upstream queue is now available under queues/kvm-upstream in the same repository. Will send it out later if there are no further remarks on this series to avoid flooding the mailing lists. Early testers are nevertheless welcome. Can the necessary changes for cleanups go in qemu.git first, so after they're merged in qemu-kvm, we can apply the unification patches. And later do the same with synchronization rework (API looks fine to me). Nice work! -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Multiple TAP Interfaces, with multiple bridges
Hi, I am having an odd networking issue. It is one of those it used to work, and now it doesn't kind of things. I can't work out what I am doing differently. I have a virtual machine, started with (among other things): -net nic,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 The ifup-ethX script inserts the tap interface into the correct bridge (of which there are multiple.) The Virtual Machine is Centos 5.3, with a 2.6.27.21 kernel. The Host is Ubuntu 9.10 with a 2.6.31 kernel. My network then looks like: The Virtual Machine has an eth0 interface, which is matched with tap0 on the host. The Virtual Machine has an eth1 interface, which is matched with tap1 on the host. The host has a bridge br0, which contains tap0 and eth0. The host has a bridge br1, which contains tap1. There is a server on the same network as the Host's eth0. The Virtual Machines eth0 interface is down. The Virtual Machines eth1 interface has an IP address of 192.168.1.10/24. The Virtual Machine has a default gateway of 192.168.1.1. The host's br0 has an IP address of 192.168.0.1/24. The host's br1 has an IP address of 192.168.1.1/24. The server has an IP address of 192.168.0.20/24, and a default gateway of 192.168.0.1. Firewalling is disabled everywhere. I have allowed time for the bridges and STP to settle. If I go to the Virtual Machine, and ping 192.168.0.20 (the server), I would expect tcpdumps to show: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host now routes from br1 to br0 * Host: tap0, no packet * Host: br0, dest MAC of Server * Host: eth0, dest MAC of Server * Server: eth0, dest MAC of Server What I actually get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not route from br0 to br1 * Host: tap0, dest MAC of ***Host's tap1/br0*** * Host: br0, dest MAC of ***Host's tap1/br0** * Host: eth0, no packet * Server: eth0, no packet As you can see, the packet has egressed *both* tap interfaces! Is this expected behaviour? What can I do about this? If I remove tap0 from the bridge, I then get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not, route from br0 to br1 * Host: tap0, no packet * Host: br0, no packet * Host: eth0, no packet * Server: eth0, no packet This is the other half of my problem: in this case, with effectively only one tap, the host is not routing between br1 and br0. The packet just gets silently dropped. Does anyone know what I am doing wrong? I hope I have managed to explain this well enough! Thanks, -- Jarrod Lowe -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3] kvmppc/booke: Set ESR and DEAR when inject interrupt to guest
On Tue, Feb 2, 2010 at 3:44 AM, Liu Yu yu@freescale.com wrote: Old method prematurely sets ESR and DEAR. Move this part after we decide to inject interrupt, which is more like hardware behave. Signed-off-by: Liu Yu yu@freescale.com Acked-by: Hollis Blanchard hol...@penguinppc.org -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Multiple TAP Interfaces, with multiple bridges
On Wednesday 03 February 2010 10:56:43 am J L wrote: Hi, I am having an odd networking issue. It is one of those it used to work, and now it doesn't kind of things. I can't work out what I am doing differently. I have a virtual machine, started with (among other things): -net nic,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 I believe this has to do with the qemu vlan support. If you don't specify the vlan= option you end up with nics on the same vlan. You need to assign the two nics to separate vlans using vlan= on each net parameter, eg: -net nic,vlan=0,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,vlan=0,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,vlan=1,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,vlan=1,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 Try that and see if you get the results you expect. Tom The ifup-ethX script inserts the tap interface into the correct bridge (of which there are multiple.) The Virtual Machine is Centos 5.3, with a 2.6.27.21 kernel. The Host is Ubuntu 9.10 with a 2.6.31 kernel. My network then looks like: The Virtual Machine has an eth0 interface, which is matched with tap0 on the host. The Virtual Machine has an eth1 interface, which is matched with tap1 on the host. The host has a bridge br0, which contains tap0 and eth0. The host has a bridge br1, which contains tap1. There is a server on the same network as the Host's eth0. The Virtual Machines eth0 interface is down. The Virtual Machines eth1 interface has an IP address of 192.168.1.10/24. The Virtual Machine has a default gateway of 192.168.1.1. The host's br0 has an IP address of 192.168.0.1/24. The host's br1 has an IP address of 192.168.1.1/24. The server has an IP address of 192.168.0.20/24, and a default gateway of 192.168.0.1. Firewalling is disabled everywhere. I have allowed time for the bridges and STP to settle. If I go to the Virtual Machine, and ping 192.168.0.20 (the server), I would expect tcpdumps to show: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host now routes from br1 to br0 * Host: tap0, no packet * Host: br0, dest MAC of Server * Host: eth0, dest MAC of Server * Server: eth0, dest MAC of Server What I actually get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not route from br0 to br1 * Host: tap0, dest MAC of ***Host's tap1/br0*** * Host: br0, dest MAC of ***Host's tap1/br0** * Host: eth0, no packet * Server: eth0, no packet As you can see, the packet has egressed *both* tap interfaces! Is this expected behaviour? What can I do about this? If I remove tap0 from the bridge, I then get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not, route from br0 to br1 * Host: tap0, no packet * Host: br0, no packet * Host: eth0, no packet * Server: eth0, no packet This is the other half of my problem: in this case, with effectively only one tap, the host is not routing between br1 and br0. The packet just gets silently dropped. Does anyone know what I am doing wrong? I hope I have managed to explain this well enough! Thanks, -- Jarrod Lowe -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Multiple TAP Interfaces, with multiple bridges
On Wednesday 03 February 2010 17:56:43 J L wrote: I am having an odd networking issue. It is one of those it used to work, and now it doesn't kind of things. I can't work out what I am doing differently. I have a virtual machine, started with (among other things): -net nic,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 This seems to be missing a vlan= option at least for the second pair: What I actually get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not route from br0 to br1 * Host: tap0, dest MAC of ***Host's tap1/br0*** * Host: br0, dest MAC of ***Host's tap1/br0** * Host: eth0, no packet * Server: eth0, no packet As you can see, the packet has egressed both tap interfaces! Is this expected behaviour? What can I do about this? Qemu forwards this packet to everything inside of the same vlan, which is 0 by default. Does it work with this? -net nic,vlan=1,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,vlan=1,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,vlan=2,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,vlan=2,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 If I remove tap0 from the bridge, I then get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not, route from br0 to br1 * Host: tap0, no packet * Host: br0, no packet * Host: eth0, no packet * Server: eth0, no packet This is the other half of my problem: in this case, with effectively only one tap, the host is not routing between br1 and br0. The packet just gets silently dropped. Does anyone know what I am doing wrong? Maybe /proc/sys/net/ipv4/ip_forward is disabled? Arnd -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[KVM-AUTOTEST PATCH] KVM test: automate handling of cdkeys in unattended_install scripts
- Automatically replace cdkeys in unattended_install scripts. A dummy string (KVM_TEST_CDKEY) is replaced by an actual cdkey (normally defined in cdkeys.cfg) before installation begins. - Make all Windows unattended scripts use the same dummy string. - Add dummy cdkeys to cdkeys.cfg.sample, for WinVista, Win2008 and Win7. These must be replaced manually by the user. Warning: this patch has undergone zero testing. Signed-off-by: Michael Goldish mgold...@redhat.com --- client/tests/kvm/cdkeys.cfg.sample | 13 +++-- client/tests/kvm/scripts/unattended.py | 17 - client/tests/kvm/unattended/win2003-32.sif |2 +- client/tests/kvm/unattended/win2003-64.sif |2 +- .../kvm/unattended/win2008-32-autounattend.xml |2 +- .../kvm/unattended/win2008-64-autounattend.xml |2 +- .../kvm/unattended/win2008-r2-autounattend.xml |2 +- .../tests/kvm/unattended/win7-32-autounattend.xml |2 +- .../tests/kvm/unattended/win7-64-autounattend.xml |2 +- .../kvm/unattended/winvista-32-autounattend.xml|2 +- .../kvm/unattended/winvista-64-autounattend.xml|2 +- client/tests/kvm/unattended/winxp32.sif|2 +- 12 files changed, 33 insertions(+), 17 deletions(-) diff --git a/client/tests/kvm/cdkeys.cfg.sample b/client/tests/kvm/cdkeys.cfg.sample index 17ec5cc..2d1d05d 100644 --- a/client/tests/kvm/cdkeys.cfg.sample +++ b/client/tests/kvm/cdkeys.cfg.sample @@ -1,8 +1,7 @@ # Copy this file to cdkeys.cfg and edit it. # # Replace the 'CDKEY' strings with real cdkeys where necessary. -# Guests that do not require cdkeys by default are commented out. -# You may uncomment them if necessary. +# Feel free to add additional guests as required. RHEL.5.3.i386: cdkey = CDKEY RHEL.5.3.x86_64: cdkey = CDKEY @@ -11,7 +10,9 @@ WinXP.32: cdkey = CDKEY WinXP.64: cdkey = CDKEY Win2003.32: cdkey = CDKEY Win2003.64: cdkey = CDKEY -#WinVista.32: cdkey = CDKEY -#WinVista.64: cdkey = CDKEY -#Win2008.32: cdkey = CDKEY -#Win2008.64: cdkey = CDKEY +WinVista.32: cdkey = CDKEY +WinVista.64: cdkey = CDKEY +Win2008.32: cdkey = CDKEY +Win2008.64: cdkey = CDKEY +Win7.32: cdkey = CDKEY +Win7.64: cdkey = CDKEY diff --git a/client/tests/kvm/scripts/unattended.py b/client/tests/kvm/scripts/unattended.py index 13f431a..87a8973 100755 --- a/client/tests/kvm/scripts/unattended.py +++ b/client/tests/kvm/scripts/unattended.py @@ -97,7 +97,22 @@ class UnattendedInstall(object): dest_fname = autounattend.xml dest = os.path.join(self.floppy_mount, dest_fname) -shutil.copyfile(self.unattended_file, dest) + +# Replace KVM_TEST_CDKEY (in the unattended file) with the cdkey +# provided for this test +unattended_contents = open(self.unattended_file).read() +dummy_cdkey_re = r'\bKVM_TEST_CDKEY\b' +real_cdkey = os.environ.get('KVM_TEST_cdkey') +if re.search(dummy_cdkey_re, unattended_contents): +if real_cdkey: +unattended_contents = re.sub(dummy_cdkey_re, real_cdkey, + unattended_contents) +else: +print (WARNING: 'cdkey' required but not specified for this + unattended installation) + +# Write the unattended file contents to 'dest' +open(dest, 'w').write(unattended_contents) if self.finish_program: dest_fname = os.path.basename(self.finish_program) diff --git a/client/tests/kvm/unattended/win2003-32.sif b/client/tests/kvm/unattended/win2003-32.sif index 901f435..5c90b03 100644 --- a/client/tests/kvm/unattended/win2003-32.sif +++ b/client/tests/kvm/unattended/win2003-32.sif @@ -25,7 +25,7 @@ OemSkipWelcome = 1 FullName = rhqe OrgName = REDHAT ComputerName = * -ProductKey = [replace-with-your-prodkey] +ProductKey = KVM_TEST_CDKEY [LicenseFilePrintData] AutoMode=PerServer diff --git a/client/tests/kvm/unattended/win2003-64.sif b/client/tests/kvm/unattended/win2003-64.sif index 9f09033..1d40d6d 100644 --- a/client/tests/kvm/unattended/win2003-64.sif +++ b/client/tests/kvm/unattended/win2003-64.sif @@ -25,7 +25,7 @@ OemSkipWelcome = 1 FullName = rhqe OrgName = REDHAT ComputerName = * -ProductKey = [replace-with-your-prodkey] +ProductKey = KVM_TEST_CDKEY [LicenseFilePrintData] AutoMode=PerServer diff --git a/client/tests/kvm/unattended/win2008-32-autounattend.xml b/client/tests/kvm/unattended/win2008-32-autounattend.xml index d8f7654..07c2889 100644 --- a/client/tests/kvm/unattended/win2008-32-autounattend.xml +++ b/client/tests/kvm/unattended/win2008-32-autounattend.xml @@ -53,7 +53,7 @@ /ImageInstall UserData ProductKey -Keyreplace-with-your-prodkey/Key +KeyKVM_TEST_CDKEY/Key WillShowUIOnError/WillShowUI /ProductKey
Re: Multiple TAP Interfaces, with multiple bridges
On 3 February 2010 17:16, a...@arndb.de wrote: On Wednesday 03 February 2010 17:56:43 J L wrote: I am having an odd networking issue. It is one of those it used to work, and now it doesn't kind of things. I can't work out what I am doing differently. I have a virtual machine, started with (among other things): -net nic,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 This seems to be missing a vlan= option at least for the second pair: What I actually get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not route from br0 to br1 * Host: tap0, dest MAC of ***Host's tap1/br0*** * Host: br0, dest MAC of ***Host's tap1/br0** * Host: eth0, no packet * Server: eth0, no packet As you can see, the packet has egressed both tap interfaces! Is this expected behaviour? What can I do about this? Qemu forwards this packet to everything inside of the same vlan, which is 0 by default. Does it work with this? -net nic,vlan=1,macaddr=fa:9e:0b:53:d2:7d,model=rtl8139 -net tap,vlan=1,script=/images/1/ifup-eth0,downscript=/images/1/ifdown-eth0 -net nic,vlan=2,macaddr=fa:02:4e:86:ed:ce,model=e1000 -net tap,vlan=2,script=/images/1/ifup-eth1,downscript=/images/1/ifdown-eth1 Thanks, both to you and Tom, who both emailed this piece of clue at the same time :) My misunderstanding was in thinking that vlan=XX would mean the packets would land on the bridge with that VLAN tag, not what it seems to actually be doing, of being used to tie one-or-more '-net nic' sections with one-or-more '-net tap' sections. That is, I though the vlan=XX was host-wide, not guest-wide. Don't know how it worked before - probably I just never noticed the extra packets. If I remove tap0 from the bridge, I then get: * VM: eth1, dest MAC of Host's tap1/br0 * Host: tap1, dest MAC of Host's tap1/br0 * Host: br1, dest MAC of Host's tap1/br0 * Host should, but does not, route from br0 to br1 * Host: tap0, no packet * Host: br0, no packet * Host: eth0, no packet * Server: eth0, no packet This is the other half of my problem: in this case, with effectively only one tap, the host is not routing between br1 and br0. The packet just gets silently dropped. Does anyone know what I am doing wrong? Maybe /proc/sys/net/ipv4/ip_forward is disabled? Sorry, forgot to mention that bit. It is '1'. I added a '-j LOG' rule to the FORWARD table (as the only rule, policy ACCEPT), and can see that the packets from the VM never make it to the FORWARD table. Arnd Thanks, -- Jarrod Lowe -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: KVM RAM limitation
On Wednesday 03 February 2010 09:55:41 am Daniel Bareiro wrote: Hi all! I'm trying to boot a VM with 2048 MB in a VMHost with Linux 2.6.32.6 and qemu-kvm-0.12.2, but when doing it, I obtain it the following message: qemu: at most 2047 MB RAM can be simulated. Are you sure you enabled KVM? Are you sure you are using the KVM binary and not some QEMU binary that's sitting around. This is one of those situations where the KVM command you are running might help. Also the same binary you are running's version ($QEMU_BIN -h | head -n1) This happened to me previously if in the VMHost I used kernel that is not x86_64 [1], but it is not the case: # uname -a Linux wilson 2.6.32.6-dgb #1 SMP Mon Feb 1 17:10:30 ART 2010 x86_64 GNU/Linux Which can be the problem? Thanks in advance for your replies. Regards, Daniel [1] https://help.ubuntu.com/community/KVM/Installation#Use%20a%2064%20bit%20ke rnel%20if%20possible -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/21] qemu-kvm: Hook cleanups and extended use of upstream code
Marcelo Tosatti wrote: On Wed, Feb 03, 2010 at 09:53:25AM +0100, Jan Kiszka wrote: This version addresses the feedback on v2, namely: - assert(vm stopped || current thread == env-thread) on low-level load/save registers - fixed mpstate initialization Yet untested is -no-kvm-irqchip with smp due to some bug in unpatched qemu-kvm or the kernel modules. Still investigating. Don't recall it ever working properly. Guess that IPI emulation with signals is problematic. OK, then it only works by chance on some boxes. Specifically, forcing qemu onto a single host core solves the issue - suspicious. Pull URL is still git://git.kiszka.org/qemu-kvm.git queues/vcpu-state PS: The corresponding upstream queue is now available under queues/kvm-upstream in the same repository. Will send it out later if there are no further remarks on this series to avoid flooding the mailing lists. Early testers are nevertheless welcome. Can the necessary changes for cleanups go in qemu.git first, so after they're merged in qemu-kvm, we can apply the unification patches. And later do the same with synchronization rework (API looks fine to me). Fine with me. Will send out my upstream queue - against uq/master or directly against qemu.git then? Nice work! Thanks, Jan -- Siemens AG, Corporate Technology, CT T DE IT 1 Corporate Competence Center Embedded Linux -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/21] qemu-kvm: Hook cleanups and extended use of upstream code
On Wed, Feb 03, 2010 at 07:02:58PM +0100, Jan Kiszka wrote: Marcelo Tosatti wrote: On Wed, Feb 03, 2010 at 09:53:25AM +0100, Jan Kiszka wrote: This version addresses the feedback on v2, namely: - assert(vm stopped || current thread == env-thread) on low-level load/save registers - fixed mpstate initialization Yet untested is -no-kvm-irqchip with smp due to some bug in unpatched qemu-kvm or the kernel modules. Still investigating. Don't recall it ever working properly. Guess that IPI emulation with signals is problematic. OK, then it only works by chance on some boxes. Specifically, forcing qemu onto a single host core solves the issue - suspicious. Pull URL is still git://git.kiszka.org/qemu-kvm.git queues/vcpu-state PS: The corresponding upstream queue is now available under queues/kvm-upstream in the same repository. Will send it out later if there are no further remarks on this series to avoid flooding the mailing lists. Early testers are nevertheless welcome. Can the necessary changes for cleanups go in qemu.git first, so after they're merged in qemu-kvm, we can apply the unification patches. And later do the same with synchronization rework (API looks fine to me). Fine with me. Will send out my upstream queue - against uq/master or directly against qemu.git then? Please send only the cleanups (up to 0160a98b9415603f583aec49b21dbd98b46ac969) for qemu.git for now, since Avi/others might have comments on the synchronization changes. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: KVM RAM limitation
On Wednesday, 03 February 2010 11:48:01 -0600, Brian Jackson wrote: I'm trying to boot a VM with 2048 MB in a VMHost with Linux 2.6.32.6 and qemu-kvm-0.12.2, but when doing it, I obtain it the following message: qemu: at most 2047 MB RAM can be simulated. Are you sure you enabled KVM? Are you sure you are using the KVM binary and not some QEMU binary that's sitting around. This is one of those situations where the KVM command you are running might help. Also the same binary you are running's version ($QEMU_BIN -h | head -n1) wilson:/usr/local/qemu-kvm/bin# ./qemu-system-x86_64 -h | head -n1 QEMU PC emulator version 0.12.2 (qemu-kvm-0.12.2), Copyright (c) 2003-2008 Fabrice Bellard The procedure that I used to compile qemu-kvm is the same of always: to download qemu-kvm-0.12.2, to install the packages (Debian) zlib1g-dev and libpci-dev, and to compile of the following way: # cd qemu-kvm-0.12.2 # ./configure --prefix=/usr/local/qemu-kvm # make # make install Until the moment I never got to use qemu-kvm with VMs of more than 2048 MB. In an installation that I have with KVM-88 and kernel x86_64 I don't have this problem. Thanks for your reply. Regards, Daniel -- Daniel Bareiro - System Administrator Fingerprint: BFB3 08D6 B4D1 31B2 72B9 29CE 6696 BF1B 14E6 1D37 Powered by Debian GNU/Linux Lenny - Linux user #188.598 signature.asc Description: Digital signature
Re: KVM RAM limitation
On 02/03/2010 01:08 PM, Daniel Bareiro wrote: On Wednesday, 03 February 2010 11:48:01 -0600, Brian Jackson wrote: I'm trying to boot a VM with 2048 MB in a VMHost with Linux 2.6.32.6 and qemu-kvm-0.12.2, but when doing it, I obtain it the following message: qemu: at most 2047 MB RAM can be simulated. Are you sure you enabled KVM? Are you sure you are using the KVM binary and not some QEMU binary that's sitting around. This is one of those situations where the KVM command you are running might help. Also the same binary you are running's version ($QEMU_BIN -h | head -n1) wilson:/usr/local/qemu-kvm/bin# ./qemu-system-x86_64 -h | head -n1 QEMU PC emulator version 0.12.2 (qemu-kvm-0.12.2), Copyright (c) 2003-2008 Fabrice Bellard The procedure that I used to compile qemu-kvm is the same of always: to download qemu-kvm-0.12.2, to install the packages (Debian) zlib1g-dev and libpci-dev, and to compile of the following way: # cd qemu-kvm-0.12.2 # ./configure --prefix=/usr/local/qemu-kvm # make # make install Until the moment I never got to use qemu-kvm with VMs of more than 2048 MB. In an installation that I have with KVM-88 and kernel x86_64 I don't have this problem. QEMU and KVM only support 2GB of memory on a 32-bit host. Both need to create a userspace mapping of the guests memory. In a 32-bit environment, you only have enough usable address space in a process to create a 2GB region. Regards, Anthony Liguori Thanks for your reply. Regards, Daniel -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: repeatable hang with loop mount and heavy IO in guest [NOT SOLVED]
On 01/23/2010 02:15 AM, Antoine Martin wrote: On 01/23/2010 01:28 AM, Antoine Martin wrote: On 01/22/2010 02:57 PM, Michael Tokarev wrote: Antoine Martin wrote: I've tried various guests, including most recent Fedora12 kernels, custom 2.6.32.x All of them hang around the same point (~1GB written) when I do heavy IO write inside the guest. [] Host is running: 2.6.31.4 QEMU PC emulator version 0.10.50 (qemu-kvm-devel-88) Please update to last version and repeat. kvm-88 is ancient and _lots_ of stuff fixed and changed since that time, I doubt anyone here will try to dig into kvm-88 problems. Current kvm is qemu-kvm-0.12.2, released yesterday. Sorry about that, I didn't realize 88 was so far behind. Upgrading to qemu-kvm-0.12.2 did solve my IO problems. Only for a while. Same problem just re-occurred, only this time it went a little further. It is now just sitting there, with a load average of exactly 3.0 (+- 5%) Here is a good trace of the symptom during writeback, you can see it write the data at around 50MB/s, it goes from being idle to sys, but after a while it just stops writing and goes into mostly wait state: total-cpu-usage -dsk/total- -net/total- ---paging-- ---system-- 1 0 99 0 0 0| 0 0 | 198B 614B| 0 0 | 3617 1 0 99 0 0 0| 0 0 | 198B 710B| 0 0 | 3117 1 1 98 0 0 0| 0 128k| 240B 720B| 0 0 | 3926 1 1 98 0 0 0| 0 0 | 132B 564B| 0 0 | 3114 1 0 99 0 0 0| 0 0 | 132B 468B| 0 0 | 3114 1 1 98 0 0 0| 0 0 | 66B 354B| 0 0 | 3013 0 4 11 85 0 0| 852k0 | 444B 1194B| 0 0 | 215 477 2 2 0 96 0 0| 500k0 | 132B 756B| 0 0 | 169 458 3 57 0 39 1 0| 228k 10M| 132B 692B| 0 0 | 476 5387 6 94 0 0 0 0| 28k 23M| 132B 884B| 0 0 | 373 2142 6 89 0 2 2 0| 40k 38M| 66B 692B| 0 8192B| 502 5651 4 47 0 48 0 0| 140k 34M| 132B 836B| 0 0 | 605 1664 3 64 0 30 2 0| 60k 50M| 132B 370B| 060k| 750 631 4 59 0 35 2 0| 48k 45M| 132B 836B| 028k| 708 1293 7 81 0 10 2 0| 68k 67M| 132B 788B| 0 124k| 928 1634 5 74 0 20 1 0| 48k 48M| 132B 756B| 0 316k| 830 5715 5 70 0 24 1 0| 168k 48M| 132B 676B| 0 100k| 734 5325 4 70 0 24 1 0| 72k 49M| 132B 948B| 088k| 776 3784 5 57 0 37 1 0| 36k 37M| 132B 996B| 0 480k| 602 369 2 21 0 77 0 0| 36k 23M| 132B 724B| 072k| 318 1033 4 51 0 43 2 0| 112k 43M| 132B 756B| 0 112k| 681 909 5 55 0 40 0 0| 88k 48M| 140B 926B| 16k 12k| 698 557 total-cpu-usage -dsk/total- -net/total- ---paging-- ---system-- usr sys idl wai hiq siq| read writ| recv send| in out | int csw 3 45 0 51 1 0|2248k 29M| 198B 1028B| 28k 44k| 681 5468 1 21 0 78 0 0| 92k 17M|1275B 2049B| 92k 52k| 328 1883 3 30 0 66 1 0| 288k 28M| 498B 2116B| 040k| 455 679 1 1 0 98 0 0|4096B0 | 394B 1340B|4096B0 | 4119 1 1 0 98 0 0| 148k 52k| 881B 1592B|4096B 44k| 7561 1 2 0 97 0 0|1408k0 | 351B 1727B| 0 0 | 110 109 2 1 0 97 0 0|8192B0 |1422B 1940B| 0 0 | 5334 1 0 0 99 0 0|4096B 12k| 328B 1018B| 0 0 | 4124 1 4 0 95 0 0| 340k0 |3075B 2152B|4096B0 | 153 191 4 7 0 89 0 0|1004k 44k|1526B 1906B| 0 0 | 254 244 0 1 0 99 0 0| 76k0 | 708B 1708B| 0 0 | 6757 1 1 0 98 0 0| 0 0 | 174B 702B| 0 0 | 3214 1 1 0 98 0 0| 0 0 | 132B 354B| 0 0 | 3211 1 0 0 99 0 0| 0 0 | 132B 468B| 0 0 | 3216 1 0 0 99 0 0| 0 0 | 132B 468B| 0 0 | 3214 1 1 0 98 0 0| 052k| 132B 678B| 0 0 | 4127 1 0 0 99 0 0| 0 0 | 198B 678B| 0 0 | 3517 1 1 0 98 0 0| 0 0 | 198B 468B| 0 0 | 3414 1 0 0 99 0 0| 0 0 | 66B 354B| 0 0 | 2811 1 0 0 99 0 0| 0 0 | 66B 354B| 0 0 | 28 9 1 1 0 98 0 0| 0 0 | 132B 468B| 0 0 | 3416 1 0 0 98 0 1| 0 0 | 66B 354B| 0 0 | 3011 1 1 0 98 0 0| 0 0 | 66B 354B| 0 0 | 2911 From that point onwards, nothing will happen. The host has disk IO to spare... So what is it waiting for?? Moved to an AMD64 host. No effect. Disabled swap before running the test. No effect. Moved the guest to a fully up-to-date FC12 server (2.6.31.6-145.fc12.x86_64), no effect. I am still seeing traces like these in dmesg (various length, but always ending in sync_page): [ 2401.350143] INFO: task perl:29512 blocked for more
Re: KVM RAM limitation
Hi, Anthony. On Wednesday, 03 February 2010 13:20:12 -0600, Anthony Liguori wrote: Are you sure you enabled KVM? Are you sure you are using the KVM binary and not some QEMU binary that's sitting around. This is one of those situations where the KVM command you are running might help. Also the same binary you are running's version ($QEMU_BIN -h | head -n1) wilson:/usr/local/qemu-kvm/bin# ./qemu-system-x86_64 -h | head -n1 QEMU PC emulator version 0.12.2 (qemu-kvm-0.12.2), Copyright (c) 2003-2008 Fabrice Bellard The procedure that I used to compile qemu-kvm is the same of always: to download qemu-kvm-0.12.2, to install the packages (Debian) zlib1g-dev and libpci-dev, and to compile of the following way: # cd qemu-kvm-0.12.2 # ./configure --prefix=/usr/local/qemu-kvm # make # make install Until the moment I never got to use qemu-kvm with VMs of more than 2048 MB. In an installation that I have with KVM-88 and kernel x86_64 I don't have this problem. QEMU and KVM only support 2GB of memory on a 32-bit host. Both need to create a userspace mapping of the guests memory. In a 32-bit environment, you only have enough usable address space in a process to create a 2GB region. But, according to what I read in the link [1] that commented, just by to have a x86_64 kernel would have to be sufficient to serve more than 2047 MB of RAM. Regards, Daniel [1] https://help.ubuntu.com/community/KVM/Installation#Use%20a%2064%20bit%20kernel%20if%20possible -- Fingerprint: BFB3 08D6 B4D1 31B2 72B9 29CE 6696 BF1B 14E6 1D37 Powered by Debian GNU/Linux Lenny - Linux user #188.598 signature.asc Description: Digital signature
[PATCH 0/4] KVM pull request: Various fixes and cleanups
As discussed in http://www.spinics.net/lists/kvm/msg28517.html, this is the first part of the KVM upstream patches developed while cleaning up qemu-kvm. Please pull from git://git.kiszka.org/qemu.git queues/kvm Jan Kiszka (4): KVM: x86: Fix up misreported CPU features KVM: Make vmport KVM-compatible KVM: Move and rename regs_modified KVM: Rework of guest debug state writing cpu-defs.h|3 ++- hw/vmport.c |3 +++ kvm-all.c | 21 - target-i386/cpu.h |9 - target-i386/kvm.c | 19 ++- 5 files changed, 39 insertions(+), 16 deletions(-) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] KVM: Rework of guest debug state writing
So far we synchronized any dirty VCPU state back into the kernel before updating the guest debug state. This was a tribute to a deficit 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. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- kvm-all.c | 12 target-i386/cpu.h |9 - target-i386/kvm.c | 11 +++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/kvm-all.c b/kvm-all.c index 67b44b5..f3e09c8 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -938,10 +938,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); } @@ -949,12 +945,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/cpu.h b/target-i386/cpu.h index 216b00e..dfc4a26 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -21,6 +21,10 @@ #include config.h +#ifdef CONFIG_KVM +#include linux/kvm.h /* for kvm_guest_debug */ +#endif + #ifdef TARGET_X86_64 #define TARGET_LONG_BITS 64 #else @@ -702,7 +706,10 @@ typedef struct CPUX86State { uint8_t has_error_code; uint32_t sipi_vector; uint32_t cpuid_kvm_features; - +#if defined(CONFIG_KVM) defined(KVM_CAP_SET_GUEST_DEBUG) +struct kvm_guest_debug kvm_guest_debug; +#endif + /* in order to simplify APIC support, we leave this pointer to the user */ struct APICState *apic_state; diff --git a/target-i386/kvm.c b/target-i386/kvm.c index f690b2e..2b3d8f6 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -851,6 +851,15 @@ int kvm_arch_put_registers(CPUState *env) if (ret 0) return ret; +/* + * Kernels before 2.6.33 overwrote flags.TF injected via SET_GUEST_DEBUG + * while updating GP regs. Work around this by updating the debug state + * once again. + */ +ret = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, env-kvm_guest_debug); +if (ret 0) +return ret; + ret = kvm_put_fpu(env); if (ret 0) return ret; @@ -1147,5 +1156,7 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg) (len_code[hw_breakpoint[n].len] (18 + n*4)); } } +/* Keep a copy for the writeback workaround in kvm_arch_put_registers */ +memcpy(env-kvm_guest_debug, dbg, sizeof(env-kvm_guest_debug)); } #endif /* KVM_CAP_SET_GUEST_DEBUG */ -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] KVM: Make vmport KVM-compatible
The vmport device accesses the VCPU registers, so it requires proper cpu_synchronize_state. Add it to vmport_ioport_read, which also synchronizes vmport_ioport_write. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/vmport.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/vmport.c b/hw/vmport.c index 884af3f..6c9d7c9 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -25,6 +25,7 @@ #include isa.h #include pc.h #include sysemu.h +#include kvm.h //#define VMPORT_DEBUG @@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) unsigned char command; uint32_t eax; +cpu_synchronize_state(env); + eax = env-regs[R_EAX]; if (eax != VMPORT_MAGIC) return eax; -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/4] KVM: Move and rename regs_modified
Touching the user space representation of KVM's VCPU state is - naturally - a per-VCPU thing. So move the dirty flag into KVM_CPU_COMMON and rename it at this chance to reflect its true meaning. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- cpu-defs.h |3 ++- kvm-all.c | 13 ++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 95068b5..7fdbe97 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -197,6 +197,7 @@ typedef struct CPUWatchpoint { const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run;\ -int kvm_fd; +int kvm_fd; \ +int kvm_vcpu_dirty; #endif diff --git a/kvm-all.c b/kvm-all.c index 15ec38e..67b44b5 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -57,7 +57,6 @@ struct KVMState KVMSlot slots[32]; int fd; int vmfd; -int regs_modified; int coalesced_mmio; int broken_set_mem_region; int migration_log; @@ -567,9 +566,9 @@ static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run) void kvm_cpu_synchronize_state(CPUState *env) { -if (!env-kvm_state-regs_modified) { +if (!env-kvm_vcpu_dirty) { kvm_arch_get_registers(env); -env-kvm_state-regs_modified = 1; +env-kvm_vcpu_dirty = 1; } } @@ -587,9 +586,9 @@ int kvm_cpu_exec(CPUState *env) break; } -if (env-kvm_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } kvm_arch_pre_run(env, run); @@ -939,9 +938,9 @@ 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_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } dbg_data-err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, dbg_data-dbg); } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] KVM: x86: Fix up misreported CPU features
From qemu-kvm: Kernels before 2.6.30 misreported some essential CPU features via KVM_GET_SUPPORTED_CPUID. Fix them up. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- target-i386/kvm.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 5b093ce..f690b2e 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -99,12 +99,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) break; case R_EDX: ret = cpuid-entries[i].edx; -if (function == 0x8001) { +switch (function) { +case 1: +/* KVM before 2.6.30 misreports the following features */ +ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA; +break; +case 0x8001: /* On Intel, kvm returns cpuid according to the Intel spec, * so add missing bits according to the AMD spec: */ cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX); ret |= cpuid_1_edx 0xdfeff7ff; +break; } break; } -- 1.6.0.2 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH 0/4] KVM pull request: Various fixes and cleanups
Hi Jan, Thanks for sending this out. On 02/03/2010 03:29 PM, Jan Kiszka wrote: As discussed in http://www.spinics.net/lists/kvm/msg28517.html, this is the first part of the KVM upstream patches developed while cleaning up qemu-kvm. I'd prefer if Marcelo/Avi took this first into qemu-kvm.git and then did a pull request for me to pull it into upstream qemu. I'm also happy to pull from multiple sources but I think the former work flow will do a better job at ensuring that qemu-kvm.git becomes the primary location of this work. Regards, Anthony Liguori Please pull from git://git.kiszka.org/qemu.git queues/kvm Jan Kiszka (4): KVM: x86: Fix up misreported CPU features KVM: Make vmport KVM-compatible KVM: Move and rename regs_modified KVM: Rework of guest debug state writing cpu-defs.h|3 ++- hw/vmport.c |3 +++ kvm-all.c | 21 - target-i386/cpu.h |9 - target-i386/kvm.c | 19 ++- 5 files changed, 39 insertions(+), 16 deletions(-) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Qemu-devel] [PATCH 0/4] KVM pull request: Various fixes and cleanups
Anthony Liguori wrote: Hi Jan, Thanks for sending this out. On 02/03/2010 03:29 PM, Jan Kiszka wrote: As discussed in http://www.spinics.net/lists/kvm/msg28517.html, this is the first part of the KVM upstream patches developed while cleaning up qemu-kvm. I'd prefer if Marcelo/Avi took this first into qemu-kvm.git and then did a pull request for me to pull it into upstream qemu. I'm also happy to pull from multiple sources but I think the former work flow will do a better job at ensuring that qemu-kvm.git becomes the primary location of this work. Whatever is preferred - but, you all, please decide at some point what you want here. :) This part of the series is easy to push around, but I'm not keen on juggling too much with the heavier parts later on. Jan signature.asc Description: OpenPGP digital signature
Re: KVM RAM limitation
On Wednesday 03 February 2010 02:06:53 pm Daniel Bareiro wrote: Hi, Anthony. On Wednesday, 03 February 2010 13:20:12 -0600, Anthony Liguori wrote: Are you sure you enabled KVM? Are you sure you are using the KVM binary and not some QEMU binary that's sitting around. This is one of those situations where the KVM command you are running might help. Also the same binary you are running's version ($QEMU_BIN -h | head -n1) wilson:/usr/local/qemu-kvm/bin# ./qemu-system-x86_64 -h | head -n1 QEMU PC emulator version 0.12.2 (qemu-kvm-0.12.2), Copyright (c) 2003-2008 Fabrice Bellard The procedure that I used to compile qemu-kvm is the same of always: to download qemu-kvm-0.12.2, to install the packages (Debian) zlib1g-dev and libpci-dev, and to compile of the following way: # cd qemu-kvm-0.12.2 # ./configure --prefix=/usr/local/qemu-kvm # make # make install Until the moment I never got to use qemu-kvm with VMs of more than 2048 MB. In an installation that I have with KVM-88 and kernel x86_64 I don't have this problem. QEMU and KVM only support 2GB of memory on a 32-bit host. Both need to create a userspace mapping of the guests memory. In a 32-bit environment, you only have enough usable address space in a process to create a 2GB region. But, according to what I read in the link [1] that commented, just by to have a x86_64 kernel would have to be sufficient to serve more than 2047 MB of RAM. The kvm userspace would also have to be compiled as a 64bit binary. Possibly statically compiled somewhere else (if that's even possible) or with a 64bit chroot. Regards, Daniel [1] https://help.ubuntu.com/community/KVM/Installation#Use%20a%2064%20bit%20ke rnel%20if%20possible -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] KVM: Rework of guest debug state writing
On Wed, Feb 03, 2010 at 10:29:45PM +0100, 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 deficit 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. Jan, This patch breaks migration. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/6] KVM: Make vmport KVM-compatible
From: Jan Kiszka jan.kis...@siemens.com The vmport device accesses the VCPU registers, so it requires proper cpu_synchronize_state. Add it to vmport_ioport_read, which also synchronizes vmport_ioport_write. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- hw/vmport.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/hw/vmport.c b/hw/vmport.c index 884af3f..6c9d7c9 100644 --- a/hw/vmport.c +++ b/hw/vmport.c @@ -25,6 +25,7 @@ #include isa.h #include pc.h #include sysemu.h +#include kvm.h //#define VMPORT_DEBUG @@ -58,6 +59,8 @@ static uint32_t vmport_ioport_read(void *opaque, uint32_t addr) unsigned char command; uint32_t eax; +cpu_synchronize_state(env); + eax = env-regs[R_EAX]; if (eax != VMPORT_MAGIC) return eax; -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/6] KVM: Request setting of nmi_pending and sipi_vector
From: Jan Kiszka jan.kis...@siemens.com The final version of VCPU events in 2.6.33 will allow to skip nmi_pending and sipi_vector on KVM_SET_VCPU_EVENTS. For now let's write them unconditionally, which is unproblematic for upstream due to missing SMP support. Future version which enable SMP will write them only on reset. Signed-off-by: Jan Kiszka jan.kis...@siemens.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com --- target-i386/kvm.c |3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 5b093ce..b457b96 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -794,6 +794,9 @@ static int kvm_put_vcpu_events(CPUState *env) events.sipi_vector = env-sipi_vector; +events.flags = +KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR; + return kvm_vcpu_ioctl(env, KVM_SET_VCPU_EVENTS, events); #else return 0; -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/6] [GIT PULL] qemu-kvm.git uq/master queue
The following changes since commit 117f8eb81dfdf51a0418fbf6d260cbb72bcd4a9d: Markus Armbruster (1): qdev: Add rudimentary help for property value are available in the git repository at: git://git.kernel.org/pub/scm/virt/kvm/qemu-kvm.git uq/master Jan Kiszka (4): KVM: Request setting of nmi_pending and sipi_vector KVM: x86: Fix up misreported CPU features KVM: Make vmport KVM-compatible KVM: Move and rename regs_modified Marcelo Tosatti (1): Fix incoming migration with iothread Sheng Yang (1): kvm: Flush coalesced MMIO buffer periodly cpu-all.h |2 ++ cpu-defs.h|3 ++- exec.c|6 ++ hw/vmport.c |3 +++ kvm-all.c | 36 +--- kvm.h |1 + target-i386/kvm.c | 11 ++- vl.c |4 8 files changed, 49 insertions(+), 17 deletions(-) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/6] KVM: x86: Fix up misreported CPU features
From: Jan Kiszka jan.kis...@siemens.com From qemu-kvm: Kernels before 2.6.30 misreported some essential CPU features via KVM_GET_SUPPORTED_CPUID. Fix them up. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- target-i386/kvm.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index b457b96..0d08cd5 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -99,12 +99,18 @@ uint32_t kvm_arch_get_supported_cpuid(CPUState *env, uint32_t function, int reg) break; case R_EDX: ret = cpuid-entries[i].edx; -if (function == 0x8001) { +switch (function) { +case 1: +/* KVM before 2.6.30 misreports the following features */ +ret |= CPUID_MTRR | CPUID_PAT | CPUID_MCE | CPUID_MCA; +break; +case 0x8001: /* On Intel, kvm returns cpuid according to the Intel spec, * so add missing bits according to the AMD spec: */ cpuid_1_edx = kvm_arch_get_supported_cpuid(env, 1, R_EDX); ret |= cpuid_1_edx 0xdfeff7ff; +break; } break; } -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/6] Fix incoming migration with iothread
Do not allow the vcpus to execute if the vm is stopped. Fixes -incoming with CONFIG_IOTHREAD enabled. Signed-off-by: Marcelo Tosatti mtosa...@redhat.com --- vl.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/vl.c b/vl.c index 50f133d..57f0ba5 100644 --- a/vl.c +++ b/vl.c @@ -3282,6 +3282,8 @@ static int cpu_can_run(CPUState *env) return 0; if (env-stopped) return 0; +if (!vm_running) +return 0; return 1; } -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/6] KVM: Move and rename regs_modified
From: Jan Kiszka jan.kis...@siemens.com Touching the user space representation of KVM's VCPU state is - naturally - a per-VCPU thing. So move the dirty flag into KVM_CPU_COMMON and rename it at this chance to reflect its true meaning. Signed-off-by: Jan Kiszka jan.kis...@siemens.com --- cpu-defs.h |3 ++- kvm-all.c | 13 ++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cpu-defs.h b/cpu-defs.h index 95068b5..7fdbe97 100644 --- a/cpu-defs.h +++ b/cpu-defs.h @@ -197,6 +197,7 @@ typedef struct CPUWatchpoint { const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run;\ -int kvm_fd; +int kvm_fd; \ +int kvm_vcpu_dirty; #endif diff --git a/kvm-all.c b/kvm-all.c index f8350c9..6c0fd37 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -57,7 +57,6 @@ struct KVMState KVMSlot slots[32]; int fd; int vmfd; -int regs_modified; int coalesced_mmio; #ifdef KVM_CAP_COALESCED_MMIO struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; @@ -574,9 +573,9 @@ void kvm_flush_coalesced_mmio_buffer(void) void kvm_cpu_synchronize_state(CPUState *env) { -if (!env-kvm_state-regs_modified) { +if (!env-kvm_vcpu_dirty) { kvm_arch_get_registers(env); -env-kvm_state-regs_modified = 1; +env-kvm_vcpu_dirty = 1; } } @@ -594,9 +593,9 @@ int kvm_cpu_exec(CPUState *env) break; } -if (env-kvm_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } kvm_arch_pre_run(env, run); @@ -946,9 +945,9 @@ 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_state-regs_modified) { +if (env-kvm_vcpu_dirty) { kvm_arch_put_registers(env); -env-kvm_state-regs_modified = 0; +env-kvm_vcpu_dirty = 0; } dbg_data-err = kvm_vcpu_ioctl(env, KVM_SET_GUEST_DEBUG, dbg_data-dbg); } -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/6] kvm: Flush coalesced MMIO buffer periodly
From: Sheng Yang sh...@linux.intel.com The default action of coalesced MMIO is, cache the writing in buffer, until: 1. The buffer is full. 2. Or the exit to QEmu due to other reasons. But this would result in a very late writing in some condition. 1. The each time write to MMIO content is small. 2. The writing interval is big. 3. No need for input or accessing other devices frequently. This issue was observed in a experimental embbed system. The test image simply print test every 1 seconds. The output in QEmu meets expectation, but the output in KVM is delayed for seconds. Per Avi's suggestion, I hooked flushing coalesced MMIO buffer in VGA update handler. By this way, We don't need vcpu explicit exit to QEmu to handle this issue. Signed-off-by: Sheng Yang sh...@linux.intel.com Signed-off-by: Marcelo Tosatti mtosa...@redhat.com --- cpu-all.h |2 ++ exec.c|6 ++ kvm-all.c | 23 +++ kvm.h |1 + vl.c |2 ++ 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/cpu-all.h b/cpu-all.h index 57b69f8..1ccc9a8 100644 --- a/cpu-all.h +++ b/cpu-all.h @@ -915,6 +915,8 @@ void qemu_register_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size); void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size); +void qemu_flush_coalesced_mmio_buffer(void); + /***/ /* host CPU ticks (if available) */ diff --git a/exec.c b/exec.c index 76831a1..67fabae 100644 --- a/exec.c +++ b/exec.c @@ -2406,6 +2406,12 @@ void qemu_unregister_coalesced_mmio(target_phys_addr_t addr, ram_addr_t size) kvm_uncoalesce_mmio_region(addr, size); } +void qemu_flush_coalesced_mmio_buffer(void) +{ +if (kvm_enabled()) +kvm_flush_coalesced_mmio_buffer(); +} + ram_addr_t qemu_ram_alloc(ram_addr_t size) { RAMBlock *new_block; diff --git a/kvm-all.c b/kvm-all.c index 15ec38e..f8350c9 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -59,6 +59,9 @@ struct KVMState int vmfd; int regs_modified; int coalesced_mmio; +#ifdef KVM_CAP_COALESCED_MMIO +struct kvm_coalesced_mmio_ring *coalesced_mmio_ring; +#endif int broken_set_mem_region; int migration_log; int vcpu_events; @@ -200,6 +203,12 @@ int kvm_init_vcpu(CPUState *env) goto err; } +#ifdef KVM_CAP_COALESCED_MMIO +if (s-coalesced_mmio !s-coalesced_mmio_ring) +s-coalesced_mmio_ring = (void *) env-kvm_run + + s-coalesced_mmio * PAGE_SIZE; +#endif + ret = kvm_arch_init_vcpu(env); if (ret == 0) { qemu_register_reset(kvm_reset_vcpu, env); @@ -466,10 +475,10 @@ int kvm_init(int smp_cpus) goto err; } +s-coalesced_mmio = 0; #ifdef KVM_CAP_COALESCED_MMIO s-coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); -#else -s-coalesced_mmio = 0; +s-coalesced_mmio_ring = NULL; #endif s-broken_set_mem_region = 1; @@ -544,14 +553,12 @@ static int kvm_handle_io(uint16_t port, void *data, int direction, int size, return 1; } -static void kvm_run_coalesced_mmio(CPUState *env, struct kvm_run *run) +void kvm_flush_coalesced_mmio_buffer(void) { #ifdef KVM_CAP_COALESCED_MMIO KVMState *s = kvm_state; -if (s-coalesced_mmio) { -struct kvm_coalesced_mmio_ring *ring; - -ring = (void *)run + (s-coalesced_mmio * TARGET_PAGE_SIZE); +if (s-coalesced_mmio_ring) { +struct kvm_coalesced_mmio_ring *ring = s-coalesced_mmio_ring; while (ring-first != ring-last) { struct kvm_coalesced_mmio *ent; @@ -609,7 +616,7 @@ int kvm_cpu_exec(CPUState *env) abort(); } -kvm_run_coalesced_mmio(env, run); +kvm_flush_coalesced_mmio_buffer(); ret = 0; /* exit loop */ switch (run-exit_reason) { diff --git a/kvm.h b/kvm.h index 1c93ac5..59cba18 100644 --- a/kvm.h +++ b/kvm.h @@ -53,6 +53,7 @@ void kvm_setup_guest_memory(void *start, size_t size); 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_insert_breakpoint(CPUState *current_env, target_ulong addr, target_ulong len, int type); diff --git a/vl.c b/vl.c index 39833fc..50f133d 100644 --- a/vl.c +++ b/vl.c @@ -2996,6 +2996,7 @@ static void gui_update(void *opaque) DisplayState *ds = opaque; DisplayChangeListener *dcl = ds-listeners; +qemu_flush_coalesced_mmio_buffer(); dpy_refresh(ds); while (dcl != NULL) { @@ -3011,6 +3012,7 @@ static void nographic_update(void *opaque) { uint64_t interval = GUI_REFRESH_INTERVAL; +qemu_flush_coalesced_mmio_buffer(); qemu_mod_timer(nographic_timer, interval + qemu_get_clock(rt_clock)); } -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org
Re: [PATCH 4/4] KVM: Rework of guest debug state writing
Marcelo Tosatti wrote: On Wed, Feb 03, 2010 at 10:29:45PM +0100, 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 deficit 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. Jan, This patch breaks migration. Can you elaborate what you did? I can't reproduce, and I do not see any conceptual issue (given that guest debugging conflicts with migration anyway). Jan signature.asc Description: OpenPGP digital signature
Re: -smp =2 + -no-kvm-irqchip broken
Gleb Natapov wrote: On Tue, Feb 02, 2010 at 07:56:42PM +0100, Jan Kiszka wrote: Jan Kiszka wrote: Gleb Natapov wrote: On Tue, Feb 02, 2010 at 05:41:03PM +0100, Jan Kiszka wrote: Gleb Natapov wrote: On Tue, Feb 02, 2010 at 05:29:53PM +0100, Jan Kiszka wrote: Hi, notice while testing v2 of my vcpu state series: Starting SMP guests like Linux or Vista without in-kernel irqchip and with more than one CPU make them lock up during boot (Vista) or spit out messages like udevd[112] trap invalid opcode ip:7fc434630950 sp:7fff3cd3fcb8 error:0 in libc-2.9.so[7fc4345b2000+14f000] Looks like interrupt is injected as exception. Can you try to bisect? Already started (as low prio background task), first looking for a good version. If you know a recent one, I'm a taker. Nope, didn't try no kernel irqchip for a long time. Kernel plays the key role here, either kvm-kmod or actually the kvm module: kvm-kmod-2.6.31.6 works, the 2.6.32 series and later do not. Digging deeper... I take this back: It works for Linux guests, but Vista crashes also with old kvm-kmod. So there is no way around real debugging. Upstream qemu-kvm/kvm works for me. Boot linux with -smp 2 and windows2008-32 with -smp 4. We seem to have two issues: - kvm.git master breaks 64-bit linux guests under -no-kvm-irqchip + smp (#UD pop up in guest user space). 2.6.33 kvm is fine. Will try to bisect this the next days. - My Vista x64 image apparently suffer from a race (I suspect in user space) that lets it deadlock on a spinlock, independent of the underlying kernel kvm version. Jan signature.asc Description: OpenPGP digital signature
Re: [Autotest] [KVM-AUTOTEST PATCH] KVM test: automate handling of cdkeys in unattended_install scripts
On Wed, Feb 3, 2010 at 3:29 PM, Michael Goldish mgold...@redhat.com wrote: - Automatically replace cdkeys in unattended_install scripts. A dummy string (KVM_TEST_CDKEY) is replaced by an actual cdkey (normally defined in cdkeys.cfg) before installation begins. - Make all Windows unattended scripts use the same dummy string. - Add dummy cdkeys to cdkeys.cfg.sample, for WinVista, Win2008 and Win7. These must be replaced manually by the user. Warning: this patch has undergone zero testing. Ok, I have tested this and it works good. Thanks Michael, applied! http://autotest.kernel.org/changeset/4200 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM test: Get rid of a duplicated function
Get rid of unload_module present on kvm_utils, since the same function is defined on autotest_lib.client.bin.utils. Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com --- client/tests/kvm/kvm_utils.py | 21 - client/tests/kvm/tests/build.py |4 ++-- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/client/tests/kvm/kvm_utils.py b/client/tests/kvm/kvm_utils.py index 7a54e57..a35d056 100644 --- a/client/tests/kvm/kvm_utils.py +++ b/client/tests/kvm/kvm_utils.py @@ -368,27 +368,6 @@ def get_git_branch(repository, branch, srcdir, commit=None, lbranch=None): return srcdir -def unload_module(module_name): - -Removes a module. Handles dependencies. If even then it's not possible -to remove one of the modules, it will trhow an error.CmdError exception. - -@param module_name: Name of the module we want to remove. - -l_raw = utils.system_output(/sbin/lsmod).splitlines() -lsmod = [x for x in l_raw if x.split()[0] == module_name] -if len(lsmod) 0: -line_parts = lsmod[0].split() -if len(line_parts) == 4: -submodules = line_parts[3].split(,) -for submodule in submodules: -unload_module(submodule) -utils.system(/sbin/modprobe -r %s % module_name) -logging.info(Module %s unloaded % module_name) -else: -logging.info(Module %s is already unloaded % module_name) - - def check_kvm_source_dir(source_dir): Inspects the kvm source directory and verifies its disposition. In some diff --git a/client/tests/kvm/tests/build.py b/client/tests/kvm/tests/build.py index 2e05a56..b569394 100644 --- a/client/tests/kvm/tests/build.py +++ b/client/tests/kvm/tests/build.py @@ -54,10 +54,10 @@ def load_kvm_modules(module_dir=None, load_stock=False, extra_modules=None): kill_qemu_processes() logging.info(Unloading previously loaded KVM modules) -kvm_utils.unload_module(kvm) +utils.unload_module(kvm) if extra_modules: for module in extra_modules: -kvm_utils.unload_module(module) +utils.unload_module(module) if module_dir: logging.info(Loading the built KVM modules...) -- 1.6.6 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] emulate accessed bit for EPT
* Rik van Riel r...@redhat.com [2010-02-03 16:11:03]: Currently KVM pretends that pages with EPT mappings never got accessed. This has some side effects in the VM, like swapping out actively used guest pages and needlessly breaking up actively used hugepages. We can avoid those very costly side effects by emulating the accessed bit for EPT PTEs, which should only be slightly costly because pages pass through page_referenced infrequently. TLB flushing is taken care of by kvm_mmu_notifier_clear_flush_young(). This seems to help prevent KVM guests from being swapped out when they should not on my system. Signed-off-by: Rik van Riel r...@redhat.com --- Jeff, does this patch fix the issue you saw a few months ago, with a 256MB KVM guest in a cgroup limited to 128GB memory? arch/x86/kvm/mmu.c | 10 -- 1 files changed, 8 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 89a49fb..6101615 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -856,9 +856,15 @@ static int kvm_age_rmapp(struct kvm *kvm, unsigned long *rmapp, u64 *spte; int young = 0; - /* always return old for EPT */ + /* + * Emulate the accessed bit for EPT, by checking if this page has + * an EPT mapping, and clearing it if it does. On the next access, + * a new EPT mapping will be established. + * This has some overhead, but not as much as the cost of swapping + * out actively used pages or breaking up actively used hugepages. + */ if (!shadow_accessed_mask) - return 0; + return kvm_unmap_rmapp(kvm, rmapp, data); Quite a clever implementation, one side effect is that one would see a larger number of minor faults with EPT enabled and an increase in allocation/frees of rmap entries, but that can be easily explained. -- Balbir -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [KVM-AUTOTEST PATCH 1/1] KVM test: kvm_vm.py: shorten VM.destroy()
On Wed, Feb 03, 2010 at 01:21:12PM +0200, Michael Goldish wrote: Call self.pci_assignable.release_devs() in the finally block. Looks good for me. Thanks, Michael, for this cleanup. Signed-off-by: Michael Goldish mgold...@redhat.com --- client/tests/kvm/kvm_vm.py | 11 ++- 1 files changed, 2 insertions(+), 9 deletions(-) diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py index 6731927..db903a0 100755 --- a/client/tests/kvm/kvm_vm.py +++ b/client/tests/kvm/kvm_vm.py @@ -598,8 +598,6 @@ class VM: # Is it already dead? if self.is_dead(): logging.debug(VM is already down) -if self.pci_assignable: -self.pci_assignable.release_devs() return logging.debug(Destroying VM with PID %d... % @@ -620,9 +618,6 @@ class VM: return finally: session.close() -if self.pci_assignable: -self.pci_assignable.release_devs() - # Try to destroy with a monitor command logging.debug(Trying to kill VM with monitor command...) @@ -632,8 +627,6 @@ class VM: # Wait for the VM to be really dead if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5): logging.debug(VM is down) -if self.pci_assignable: -self.pci_assignable.release_devs() return # If the VM isn't dead yet... @@ -643,13 +636,13 @@ class VM: # Wait for the VM to be really dead if kvm_utils.wait_for(self.is_dead, 5, 0.5, 0.5): logging.debug(VM is down) -if self.pci_assignable: -self.pci_assignable.release_devs() return logging.error(Process %s is a zombie! % self.process.get_pid()) finally: +if self.pci_assignable: +self.pci_assignable.release_devs() if self.process: self.process.close() try: -- 1.5.4.1 -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] KVM test: Replace some kvm_subprocess usage with utils.system
The preprocessing command and qemu-img command are currently ran using kvm_subprocess. However, those commands have no need to use that API, considering that we don't need to interact with those commands or make them persist between tests. Using utils.system() instead of kvm_subprocess speeds up the command execution, and simplifies the code a bit. Signed-off-by: Lucas Meneghel Rodrigues l...@redhat.com --- client/tests/kvm/kvm_preprocessing.py | 17 +++-- client/tests/kvm/kvm_vm.py| 28 2 files changed, 19 insertions(+), 26 deletions(-) diff --git a/client/tests/kvm/kvm_preprocessing.py b/client/tests/kvm/kvm_preprocessing.py index 53fa2cb..8a0c151 100644 --- a/client/tests/kvm/kvm_preprocessing.py +++ b/client/tests/kvm/kvm_preprocessing.py @@ -1,5 +1,5 @@ import sys, os, time, commands, re, logging, signal, glob -from autotest_lib.client.bin import test +from autotest_lib.client.bin import test, utils from autotest_lib.client.common_lib import error import kvm_vm, kvm_utils, kvm_subprocess, ppm_utils try: @@ -142,17 +142,14 @@ def process_command(test, params, env, command, command_timeout, for k in params.keys(): os.putenv(KVM_TEST_%s % k, str(params[k])) # Execute command -logging.info(Executing command '%s'... % command) -(status, output) = kvm_subprocess.run_fg(cd %s; %s % (test.bindir, -command), - logging.debug, (command) , - timeout=command_timeout) -if status != 0: -logging.warn(Custom processing command failed: '%s'; Output is: %s % -(command, output)) +try: +utils.system(cd %s; %s % (test.bindir, command)) +except error.CmdError, e: +logging.warn(Custom processing command '%s' failed, output is: %s, + command, str(e)) if not command_noncritical: raise error.TestError(Custom processing command failed: %s % - output) + str(e)) def process(test, params, env, image_func, vm_func): diff --git a/client/tests/kvm/kvm_vm.py b/client/tests/kvm/kvm_vm.py index db903a0..d7b3608 100755 --- a/client/tests/kvm/kvm_vm.py +++ b/client/tests/kvm/kvm_vm.py @@ -7,6 +7,9 @@ Utility classes and functions to handle Virtual Machine creation using qemu. import time, socket, os, logging, fcntl, re, commands import kvm_utils, kvm_subprocess +import common +from autotest_lib.client.common_lib import error +from autotest_lib.client.bin import utils def get_image_filename(params, root_dir): @@ -53,20 +56,13 @@ def create_image(params, root_dir): size = params.get(image_size, 10G) qemu_img_cmd += %s % size -logging.debug(Running qemu-img command:\n%s % qemu_img_cmd) -(status, output) = kvm_subprocess.run_fg(qemu_img_cmd, logging.debug, - (qemu-img) , timeout=120) - -if status is None: -logging.error(Timeout elapsed while waiting for qemu-img command - to complete:\n%s % qemu_img_cmd) -return None -elif status != 0: -logging.error(Could not create image; - qemu-img command failed:\n%s % qemu_img_cmd) -logging.error(Status: %s % status) -logging.error(Output: + kvm_utils.format_str_for_message(output)) +try: +utils.system(qemu_img_cmd) +except error.CmdError, e: +logging.error(Could not create image; qemu-img command failed:\n%s, + str(e)) return None + if not os.path.exists(image_filename): logging.error(Image could not be created for some reason; qemu-img command:\n%s % qemu_img_cmd) -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 00/21] qemu-kvm: Hook cleanups and extended use of upstream code
On Wed, Feb 03, 2010 at 02:50:51PM -0200, Marcelo Tosatti wrote: On Wed, Feb 03, 2010 at 09:53:25AM +0100, Jan Kiszka wrote: This version addresses the feedback on v2, namely: - assert(vm stopped || current thread == env-thread) on low-level load/save registers - fixed mpstate initialization Yet untested is -no-kvm-irqchip with smp due to some bug in unpatched qemu-kvm or the kernel modules. Still investigating. Don't recall it ever working properly. Guess that IPI emulation with signals is problematic. It did for me. -- Gleb. -- To unsubscribe from this list: send the line unsubscribe kvm in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/4] kvmppc: guest debug definitions
Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { + __u32 exception; + __u32 pc; + __u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { + struct { + __u32 addr; + __u32 type; + } bp[6]; }; #endif /* __LINUX_KVM_POWERPC_H */ diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 5e5bae7..a364832 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -157,6 +157,18 @@ struct hpte_cache { struct kvmppc_pte pte; }; +struct kvmppc_debug_reg { + u32 dbcr0; + u32 iac[0]; + u32 iac1; + u32 iac2; + u32 iac3; + u32 iac4; + u32 dac[0]; + u32 dac1; + u32 dac2; +}; + struct kvm_vcpu_arch { ulong host_stack; u32 host_pid; @@ -240,6 +252,9 @@ struct kvm_vcpu_arch { u32 dbcr1; u32 dbsr; + struct kvmppc_debug_reg shadow_dbg_reg; + struct kvmppc_debug_reg host_dbg_reg; + #ifdef CONFIG_KVM_EXIT_TIMING struct kvmppc_exit_timing timing_exit; struct kvmppc_exit_timing timing_last_enter; @@ -274,6 +289,7 @@ struct kvm_vcpu_arch { struct tasklet_struct tasklet; u64 dec_jiffies; unsigned long pending_exceptions; + struct kvm_guest_debug_arch dbg; #ifdef CONFIG_PPC64 struct hpte_cache hpte_cache[HPTEG_CACHE_NUM]; -- 1.6.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/4] kvmppc/booke: switch shadow/host debug registers on guest enter/exit path
This provide a precise way to avoid confounding settings of guest and host. Also the guest hardware emulation about debug can be implemented based on this. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kernel/asm-offsets.c |3 ++ arch/powerpc/kvm/booke_interrupts.S | 58 +++ 2 files changed, 61 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 957ceb7..67e978d 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -425,6 +425,9 @@ int main(void) DEFINE(VCPU_LAST_INST, offsetof(struct kvm_vcpu, arch.last_inst)); DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); + DEFINE(VCPU_SHADOW_DBG, offsetof(struct kvm_vcpu, arch.shadow_dbg_reg)); + DEFINE(VCPU_HOST_DBG, offsetof(struct kvm_vcpu, arch.host_dbg_reg)); + DEFINE(VCPU_GUEST_DEBUG, offsetof(struct kvm_vcpu, guest_debug)); /* book3s_64 */ #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 380a78c..644ff1d 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -168,6 +168,26 @@ _GLOBAL(kvmppc_resume_host) stw r9, VCPU_FAULT_ESR(r4) ..skip_esr: + lwz r6, VCPU_GUEST_DEBUG(r4) + or. r6, r6, r6 + beq ..skip_load_host_debug + addir7, r4, VCPU_HOST_DBG - 4 + lwzur9, 4(r7) + mtspr SPRN_DBCR0, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC1, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC2, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC3, r9 + lwzur9, 4(r7) + mtspr SPRN_IAC4, r9 + lwzur9, 4(r7) + mtspr SPRN_DAC1, r9 + lwzur9, 4(r7) + mtspr SPRN_DAC2, r9 +..skip_load_host_debug: + /* Save remaining volatile guest register state to vcpu. */ stw r0, VCPU_GPR(r0)(r4) stw r1, VCPU_GPR(r1)(r4) @@ -392,6 +412,44 @@ lightweight_exit: lwz r3, VCPU_SPRG7(r4) mtspr SPRN_SPRG7W, r3 + lwz r6, VCPU_GUEST_DEBUG(r4) + or. r6, r6, r6 + beq ..skip_load_guest_debug + mfmsr r7 + rlwinm r7, r7, 0, ~MSR_DE + mtmsr r7 + addir7, r4, VCPU_HOST_DBG - 4 + mfspr r8, SPRN_DBCR0 + stwur8, 4(r7) + mfspr r8, SPRN_IAC1 + stwur8, 4(r7) + mfspr r8, SPRN_IAC2 + stwur8, 4(r7) + mfspr r8, SPRN_IAC3 + stwur8, 4(r7) + mfspr r8, SPRN_IAC4 + stwur8, 4(r7) + mfspr r8, SPRN_DAC1 + stwur8, 4(r7) + mfspr r8, SPRN_DAC2 + stwur8, 4(r7) + addir7, r4, VCPU_SHADOW_DBG - 4 + lwzur8, 4(r7) + mtspr SPRN_DBCR0, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC1, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC2, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC3, r8 + lwzur8, 4(r7) + mtspr SPRN_IAC4, r8 + lwzur8, 4(r7) + mtspr SPRN_DAC1, r8 + lwzur8, 4(r7) + mtspr SPRN_DAC2, r8 +..skip_load_guest_debug: + #ifdef CONFIG_KVM_EXIT_TIMING /* save enter time */ 1: -- 1.6.4 -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 +++ arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof(kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) +{ + int gtlb_index; + gpa_t gpa; + gfn_t gfn; + struct page *page; + void *headdr, *from; + + /* Check the guest TLB. */ + gtlb_index = kvmppc_mmu_itlb_index(vcpu, geaddr); + if (gtlb_index 0) + return -EFAULT; + + gpa = kvmppc_mmu_xlate(vcpu, gtlb_index, geaddr); + gfn = gpa PAGE_SHIFT; + + page = gfn_to_page(vcpu-kvm, gfn); + if (page == bad_page) + return -EFAULT; + + headdr = kmap_atomic(page, KM_USER0); + if (!headdr) + return -EFAULT; + from = headdr + (geaddr (PAGE_SIZE - 1)); + memcpy(data, from, len); + kunmap_atomic(headdr, KM_USER0); + + return 0; +} + +static unsigned int kvmppc_guest_debug_exitnr_fixup(struct kvm_vcpu *vcpu, + unsigned int exit_nr) +{ + unsigned int ret = exit_nr; + + u32 csrr0 = mfspr(SPRN_CSRR0); + u32 dbsr = mfspr(SPRN_DBSR); + + if ((dbsr | DBSR_IC) + csrr0 = kvmppc_booke_handlers + csrr0 kvmppc_booke_handlers + (PAGE_SIZE VCPU_SIZE_ORDER)) { + int i = 0; + + for (i = 0; i handler_vector_num; i++) { + if (kvmppc_booke_handler_addr[i] + csrr0 == kvmppc_booke_handler_addr[i] + 4) { + mtspr(SPRN_DBSR, ~0); + ret = i; + break; + } + } + + } + + switch (ret) { + case BOOKE_INTERRUPT_DEBUG: + case BOOKE_INTERRUPT_ITLB_MISS: + case BOOKE_INTERRUPT_EXTERNAL: + case BOOKE_INTERRUPT_DECREMENTER: + break; + + case BOOKE_INTERRUPT_PROGRAM: + case BOOKE_INTERRUPT_DTLB_MISS: + /* Need to save the last instruction */ + kvmppc_read_guest(vcpu, vcpu-arch.pc, vcpu-arch.last_inst, 4); + break; + default: + printk(Unhandled debug after interrupt:%d\n, ret); + } + + return ret; +} + /** * kvmppc_handle_exit * @@ -233,6 +310,9 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu, run-exit_reason = KVM_EXIT_UNKNOWN; run-ready_for_interrupt_injection = 1; + if (unlikely(exit_nr == BOOKE_INTERRUPT_DEBUG)) + exit_nr = kvmppc_guest_debug_exitnr_fixup(vcpu, exit_nr); + switch (exit_nr) { case BOOKE_INTERRUPT_MACHINE_CHECK: printk(MACHINE CHECK: %lx\n, mfspr(SPRN_MCSR)); @@ -686,6 +766,8 @@ int __init kvmppc_booke_init(void) memcpy((void *)kvmppc_booke_handlers + ivor[i], kvmppc_handlers_start + i * kvmppc_handler_len, kvmppc_handler_len); + kvmppc_booke_handler_addr[i] = + (unsigned long)kvmppc_booke_handlers + ivor[i]; } flush_icache_range(kvmppc_booke_handlers, kvmppc_booke_handlers + max_ivor + kvmppc_handler_len); diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 644ff1d..fdc48c1 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -42,16 +42,17 @@ #define HOST_STACK_LR (HOST_STACK_SIZE + 4) /* In caller stack frame. */ #define NEED_INST_MASK ((1BOOKE_INTERRUPT_PROGRAM)
Re: [PATCH 1/4] kvmppc: guest debug definitions
Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Alex + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. I'd also prefer to see addr be u64. On 32 bit targets we can just use the lower 32 bits only. Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 ++ + arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof (kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) Ah, nice. I have something similar in book3s.c. IIRC it's called kvmppc_ld. I think we should make the semantics identical and declare it as common kvmppc_core function. Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/4] kvmppc: guest debug definitions
-Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 4:57 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Just an invalid instruction which can generate program interrupt... I'm open to it's value btw. + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. Yes it's used by ioctl. What's the usually pad size? -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/4] kvmppc: guest debug definitions
Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 4:57 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Just an invalid instruction which can generate program interrupt... I'm open to it's value btw. Well this definitely doesn't generate a program interrupt. Or at least it shouldn't :-). I just remembered where I've seen an opcode like this before. This is a part of a dump of arch/powerpc/boot/ps3-hvcall.o lv1_get_logical_ppe_id: 0: 7c 08 02 a6 mflrr0 4: 90 01 00 04 stw r0,4(r1) 8: 94 21 ff f0 stwur1,-16(r1) c: 90 61 00 08 stw r3,8(r1) 10: 39 60 00 45 li r11,69 14: 44 00 00 22 sc 1 So as you can see, this is the hypercall instruction for lv1. IIRC beat uses the same. I don't think we want to reuse that opcode for ourselves. Maybe one day someone figures it's a good idea to implement a beat-style ABI in KVM. But IIRC sc can take a lot of values, so we can just take sc 0x1234 or so :-). + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. Yes it's used by ioctl. What's the usually pad size? I don't think there's a default. I just tend to pad it to something reasonable. I guess in this case we can even just extend bp to 128 entries, add a reasonable amount of churn to the debug info and be good: struct kvm_guest_debug_arch { struct { __u64 addr; __u32 type; __u32 pad1; __u64 pad2; } bp[128]; } This should be enough to even leverage performance monitoring stuff later on that would be able to check if r1 == 0x1234 and then stop :-). Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
-Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. Thus, we'll see that an single step interrupt happens at the beginning of guest exit path. Then we need to recognize this kind of single step interrupt and fix the exit_nr to the original value. So that everything looks like normal. Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/kvm/booke.c| 82 ++ + arch/powerpc/kvm/booke_interrupts.S |9 ++-- 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c index ec2722d..9056708 100644 --- a/arch/powerpc/kvm/booke.c +++ b/arch/powerpc/kvm/booke.c @@ -24,6 +24,7 @@ #include linux/module.h #include linux/vmalloc.h #include linux/fs.h +#include linux/highmem.h #include asm/cputable.h #include asm/uaccess.h @@ -34,6 +35,8 @@ #include booke.h unsigned long kvmppc_booke_handlers; +unsigned long kvmppc_booke_handler_addr[16]; +#define handler_vector_num (sizeof(kvmppc_booke_handler_addr)/sizeof (kvmppc_booke_handler_addr[0])) #define VM_STAT(x) offsetof(struct kvm, stat.x), KVM_STAT_VM #define VCPU_STAT(x) offsetof(struct kvm_vcpu, stat.x), KVM_STAT_VCPU @@ -214,6 +217,80 @@ void kvmppc_core_deliver_interrupts(struct kvm_vcpu *vcpu) } } +int kvmppc_read_guest(struct kvm_vcpu *vcpu, unsigned long geaddr, + void *data, int len) Ah, nice. I have something similar in book3s.c. IIRC it's called kvmppc_ld. I think we should make the semantics identical and declare it as common kvmppc_core function. Cool. -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step
Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 5:03 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 4/4] kvmppc/booke: exit_nr fixup for guest debug single step Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: As BOOKE doesn't have hardware support for virtualization, hardware never know who's guest and host. When enable hardware single step in guest, we cannot disabled it at the point we switch back to host. Why not? We directly arrive in our code. So we can just disable it, no? Or does that break when you'd try to debug the guest interrupt handlers? That's the hardware limitition. Assume received itlb miss interrupt, but it doesn't clear MSR_DE in MSR, so on the exit path single step still work and then debug interrupt is triggled. MSRDE is set to 0 by critical class interrupts unless Category E.ED is supported, by Debug interrupts, and by Machine Check interrupts, and is left unchanged by all other interrupts. Great. So when single stepping is enabled, you jump into the guest, get an itlb miss, get out, still have DE set, get in KVM's own DE handler and can process things from there. Could you check if the debug instruction was on PR=0? If so, you can just rfi and be good, right? Alex -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/4] kvmppc: guest debug definitions
-Original Message- From: Alexander Graf [mailto:ag...@suse.de] Sent: Wednesday, February 03, 2010 5:51 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Liu Yu-B13201 wrote: -Original Message- From: kvm-ppc-ow...@vger.kernel.org [mailto:kvm-ppc-ow...@vger.kernel.org] On Behalf Of Alexander Graf Sent: Wednesday, February 03, 2010 4:57 PM To: Liu Yu-B13201 Cc: hol...@penguinppc.org; kvm-ppc@vger.kernel.org; k...@vger.kernel.org; Liu Yu-B13201 Subject: Re: [PATCH 1/4] kvmppc: guest debug definitions Am 03.02.2010 um 08:53 schrieb Liu Yu yu@freescale.com: Signed-off-by: Liu Yu yu@freescale.com --- arch/powerpc/include/asm/kvm.h | 20 arch/powerpc/include/asm/kvm_host.h | 16 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/ asm/kvm.h index 81f3b0b..b7f7861 100644 --- a/arch/powerpc/include/asm/kvm.h +++ b/arch/powerpc/include/asm/kvm.h @@ -22,6 +22,9 @@ #include linux/types.h +/* Select powerpc specific features in linux/kvm.h */ +#define __KVM_HAVE_GUEST_DEBUG + struct kvm_regs { __u64 pc; __u64 cr; @@ -71,10 +74,27 @@ struct kvm_fpu { }; struct kvm_debug_exit_arch { +__u32 exception; +__u32 pc; +__u32 status; }; +#define KVM_INST_GUESTGDB 0x4422 What instruction is this again? :) Is it something reserved for purposes like this? Just an invalid instruction which can generate program interrupt... I'm open to it's value btw. Well this definitely doesn't generate a program interrupt. Or at least it shouldn't :-). I just remembered where I've seen an opcode like this before. This is a part of a dump of arch/powerpc/boot/ps3-hvcall.o lv1_get_logical_ppe_id: 0: 7c 08 02 a6 mflrr0 4: 90 01 00 04 stw r0,4(r1) 8: 94 21 ff f0 stwur1,-16(r1) c: 90 61 00 08 stw r3,8(r1) 10: 39 60 00 45 li r11,69 14: 44 00 00 22 sc 1 So as you can see, this is the hypercall instruction for lv1. IIRC beat uses the same. I don't think we want to reuse that opcode for ourselves. Maybe one day someone figures it's a good idea to implement a beat-style ABI in KVM. But IIRC sc can take a lot of values, so we can just take sc 0x1234 or so :-). + +#define KVM_GUESTDBG_USE_SW_BP 0x0001 +#define KVM_GUESTDBG_USE_HW_BP 0x0002 + +#define KVMPPC_DEBUG_NOTYPE 0x0 +#define KVMPPC_DEBUG_BREAKPOINT (1UL 1) +#define KVMPPC_DEBUG_WATCH_WRITE(1UL 2) +#define KVMPPC_DEBUG_WATCH_READ (1UL 3) + /* for KVM_SET_GUEST_DEBUG */ struct kvm_guest_debug_arch { +struct { +__u32 addr; +__u32 type; +} bp[6]; I can't look up the sources right now. Is this a struct that 1:1 maps to an ioctl struct? If so, we should add padding for a possible future extension of debug registers. Yes it's used by ioctl. What's the usually pad size? I don't think there's a default. I just tend to pad it to something reasonable. I guess in this case we can even just extend bp to 128 entries, add a reasonable amount of churn to the debug info and be good: struct kvm_guest_debug_arch { struct { __u64 addr; __u32 type; __u32 pad1; __u64 pad2; } bp[128]; } Software breakpoint is maintained by qemu. Here it's only used by hardware breakpoint/watchpoint Is 128 much too large? -- To unsubscribe from this list: send the line unsubscribe kvm-ppc in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html