Re: [kvm-devel] [PATCH RFC 2/5] Create relay channels and add trace data
Liu, Eric E wrote: From 41d65b55580d3f07f9f1c50e89e3d64c5d10fbaf Mon Sep 17 00:00:00 2001 From: Feng (Eric) Liu [EMAIL PROTECTED] Date: Tue, 1 Apr 2008 07:26:14 -0400 Subject: [PATCH] KVM: Add kvm trace support. when config KVM_TRACE, it allows userspace app to read the trace of kvm_related events through the relayfs. +int kvm_trace_ioctl(unsigned int ioctl, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + long r = -EINVAL; + + switch (ioctl) { + case KVM_TRACE_ENABLE: + r = kvm_trace_enable(argp); + break; + case KVM_TRACE_DISABLE: + r = 0; + kvm_trace_cleanup(); + break; + } + + return r; +} Since we want to allow non-privileged users to open /dev/kvm, and tracing can provide data on other users' VMs, we need check on CAP_SYS_ADMIN (or maybe CAP_PTRACE?) and return -EPERM if the user is not privileged enough. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [patch 0/3] separate thread for IO handling V3
Marcelo Tosatti wrote: This version fixes the vmdk problems found by the regression testing. Dor, regarding the option to disable the IO thread, it would require duplicating most of the changed code. For now I believe its better to get the patch into a state where its considered stable enough for inclusion. Please rerun the regression tests. Thanks. The regression tests are happy. There's still something wrong. When I start Windows with these patches applied, Windows startup consumes ~50 sec of cpu time, compared to ~12 sec without. Pinning qemu into cpu 0 seems to fix this. I'll investigate some more. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Andrea Arcangeli wrote: On Wed, Apr 02, 2008 at 02:16:41PM +0300, Avi Kivity wrote: Ugh, there's still mark_page_accessed() and SetPageDirty(). btw, like PG_dirty is only set if the spte is writeable, mark_page_accessed should only run if the accessed bit is set in the spte. It doesn't matter now as nobody could possibly clear it, No one will clear it now, but it can start out cleared. This is done on speculative mmu_set_spte(): when the guest writes into its page tables, we update the spte speculatively, but the guest may not actually access that location (for example, due to a page fault clustering). So the change makes sense even now. It still skips an atomic op. Your plan still sounds just fine despite the above, infact it sounds too perfect: the awk hack to re-add the refcounting when building the external module if CONFIG_MMU_NOTIFIER isn't defined is going to be messy, a plain CONFIG_MMU_NOTIFIER in kvm.git would be simpler and more robust IMHO even if less perfect :). Worst case, we stick a get_user_pages() inside the memslot setup function. That makes things not swappable for pre-mmu notifiers, but completely safe. I'd rather avoid special casing the core code, whenever possible. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [patch 0/3] separate thread for IO handling V3
Avi Kivity wrote: There's still something wrong. When I start Windows with these patches applied, Windows startup consumes ~50 sec of cpu time, compared to ~12 sec without. Pinning qemu into cpu 0 seems to fix this. I'll investigate some more. Changing GUI_REFRESH_INTERVAL to 1000 (from 30) reduces cpu usage back to normal. So I'm guessing there's some bad interaction between the iothread getting the dirty log and vcpu 0. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [patch 0/3] separate thread for IO handling V3
Avi Kivity wrote: Avi Kivity wrote: There's still something wrong. When I start Windows with these patches applied, Windows startup consumes ~50 sec of cpu time, compared to ~12 sec without. Pinning qemu into cpu 0 seems to fix this. I'll investigate some more. Changing GUI_REFRESH_INTERVAL to 1000 (from 30) reduces cpu usage back to normal. So I'm guessing there's some bad interaction between the iothread getting the dirty log and vcpu 0. Turns out we held slots_lock while in guest mode (which we can be in for unbounded time). Dropping the lock restored behavior to normal, so I'm applying the patches. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 17/35] KVM: Add reset support for in kernel PIT
From: Sheng Yang [EMAIL PROTECTED] Separate the reset part and prepare for reset support. Signed-off-by: Sheng Yang [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/i8254.c | 30 +++--- arch/x86/kvm/i8254.h |1 + 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 7776f50..06a241a 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c @@ -476,12 +476,28 @@ static int speaker_in_range(struct kvm_io_device *this, gpa_t addr) return (addr == KVM_SPEAKER_BASE_ADDRESS); } -struct kvm_pit *kvm_create_pit(struct kvm *kvm) +void kvm_pit_reset(struct kvm_pit *pit) { int i; + struct kvm_kpit_channel_state *c; + + mutex_lock(pit-pit_state.lock); + for (i = 0; i 3; i++) { + c = pit-pit_state.channels[i]; + c-mode = 0xff; + c-gate = (i != 2); + pit_load_count(pit-kvm, i, 0); + } + mutex_unlock(pit-pit_state.lock); + + atomic_set(pit-pit_state.pit_timer.pending, 0); + pit-pit_state.inject_pending = 1; +} + +struct kvm_pit *kvm_create_pit(struct kvm *kvm) +{ struct kvm_pit *pit; struct kvm_kpit_state *pit_state; - struct kvm_kpit_channel_state *c; pit = kzalloc(sizeof(struct kvm_pit), GFP_KERNEL); if (!pit) @@ -510,17 +526,9 @@ struct kvm_pit *kvm_create_pit(struct kvm *kvm) pit_state-pit = pit; hrtimer_init(pit_state-pit_timer.timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); - atomic_set(pit_state-pit_timer.pending, 0); - for (i = 0; i 3; i++) { - c = pit_state-channels[i]; - c-mode = 0xff; - c-gate = (i != 2); - pit_load_count(kvm, i, 0); - } - mutex_unlock(pit-pit_state.lock); - pit-pit_state.inject_pending = 1; + kvm_pit_reset(pit); return pit; } diff --git a/arch/x86/kvm/i8254.h b/arch/x86/kvm/i8254.h index 586bbf0..e63ef38 100644 --- a/arch/x86/kvm/i8254.h +++ b/arch/x86/kvm/i8254.h @@ -57,5 +57,6 @@ void kvm_pit_timer_intr_post(struct kvm_vcpu *vcpu, int vec); void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val); struct kvm_pit *kvm_create_pit(struct kvm *kvm); void kvm_free_pit(struct kvm *kvm); +void kvm_pit_reset(struct kvm_pit *pit); #endif -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 11/35] KVM: detect if VCPU triple faults
From: Joerg Roedel [EMAIL PROTECTED] In the current inject_page_fault path KVM only checks if there is another PF pending and injects a DF then. But it has to check for a pending DF too to detect a shutdown condition in the VCPU. If this is not detected the VCPU goes to a PF - DF - PF loop when it should triple fault. This patch detects this condition and handles it with an KVM_SHUTDOWN exit to userspace. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c | 20 +++- include/linux/kvm_host.h |1 + 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index dbcff38..491eda3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -155,11 +155,16 @@ void kvm_inject_page_fault(struct kvm_vcpu *vcpu, unsigned long addr, u32 error_code) { ++vcpu-stat.pf_guest; - if (vcpu-arch.exception.pending vcpu-arch.exception.nr == PF_VECTOR) { - printk(KERN_DEBUG kvm: inject_page_fault: - double fault 0x%lx\n, addr); - vcpu-arch.exception.nr = DF_VECTOR; - vcpu-arch.exception.error_code = 0; + if (vcpu-arch.exception.pending) { + if (vcpu-arch.exception.nr == PF_VECTOR) { + printk(KERN_DEBUG kvm: inject_page_fault: +double fault 0x%lx\n, addr); + vcpu-arch.exception.nr = DF_VECTOR; + vcpu-arch.exception.error_code = 0; + } else if (vcpu-arch.exception.nr == DF_VECTOR) { + /* triple fault - shutdown */ + set_bit(KVM_REQ_TRIPLE_FAULT, vcpu-requests); + } return; } vcpu-arch.cr2 = addr; @@ -2676,6 +2681,11 @@ again: r = 0; goto out; } + if (test_and_clear_bit(KVM_REQ_TRIPLE_FAULT, vcpu-requests)) { + kvm_run-exit_reason = KVM_EXIT_SHUTDOWN; + r = 0; + goto out; + } } kvm_inject_pending_timer_irqs(vcpu); diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 9750bb3..958e003 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -38,6 +38,7 @@ #define KVM_REQ_MIGRATE_TIMER 1 #define KVM_REQ_REPORT_TPR_ACCESS 2 #define KVM_REQ_MMU_RELOAD 3 +#define KVM_REQ_TRIPLE_FAULT 4 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 20/35] KVM: Provide unlocked version of emulator_write_phys()
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c | 21 ++--- include/asm-x86/kvm_host.h |3 +++ 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 1b9e695..03ba402 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1840,22 +1840,29 @@ mmio: return X86EMUL_UNHANDLEABLE; } -static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, - const void *val, int bytes) +int __emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, + const void *val, int bytes) { int ret; - down_read(vcpu-kvm-slots_lock); ret = kvm_write_guest(vcpu-kvm, gpa, val, bytes); - if (ret 0) { - up_read(vcpu-kvm-slots_lock); + if (ret 0) return 0; - } kvm_mmu_pte_write(vcpu, gpa, val, bytes); - up_read(vcpu-kvm-slots_lock); return 1; } +static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, + const void *val, int bytes) +{ + int ret; + + down_read(vcpu-kvm-slots_lock); + ret =__emulator_write_phys(vcpu, gpa, val, bytes); + up_read(vcpu-kvm-slots_lock); + return ret; +} + static int emulator_write_emulated_onepage(unsigned long addr, const void *val, unsigned int bytes, diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 12932bb..c8e51f8 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -431,6 +431,9 @@ void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); +int __emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, + const void *val, int bytes); + enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 19/35] x86: KVM guest: add basic paravirt support
From: Marcelo Tosatti [EMAIL PROTECTED] Add basic KVM paravirt support. Avoid vm-exits on IO delays. Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/Kconfig |8 ++ arch/x86/kernel/Makefile |1 + arch/x86/kernel/kvm.c | 52 arch/x86/kernel/setup_32.c |1 + arch/x86/kernel/setup_64.c |2 + include/linux/kvm_para.h |6 + 6 files changed, 70 insertions(+), 0 deletions(-) create mode 100644 arch/x86/kernel/kvm.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e59ea05..75d2700 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -381,6 +381,14 @@ config KVM_CLOCK provides the guest with timing infrastructure such as time of day, and system time +config KVM_GUEST + bool KVM Guest support + select PARAVIRT + depends on !(X86_VISWS || X86_VOYAGER) + help +This option enables various optimizations for running under the KVM +hypervisor. + source arch/x86/lguest/Kconfig config PARAVIRT diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index a3379a3..1cc9d42 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST)+= test_nx.o obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o +obj-$(CONFIG_KVM_GUEST)+= kvm.o obj-$(CONFIG_KVM_CLOCK)+= kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c new file mode 100644 index 000..a8e36da --- /dev/null +++ b/arch/x86/kernel/kvm.c @@ -0,0 +1,52 @@ +/* + * KVM paravirt_ops implementation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright (C) 2007, Red Hat, Inc., Ingo Molnar [EMAIL PROTECTED] + * Copyright IBM Corporation, 2007 + * Authors: Anthony Liguori [EMAIL PROTECTED] + */ + +#include linux/module.h +#include linux/kernel.h +#include linux/kvm_para.h +#include linux/cpu.h +#include linux/mm.h + +/* + * No need for any IO delay on KVM + */ +static void kvm_io_delay(void) +{ +} + +static void paravirt_ops_setup(void) +{ + pv_info.name = KVM; + pv_info.paravirt_enabled = 1; + + if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) + pv_cpu_ops.io_delay = kvm_io_delay; + +} + +void __init kvm_guest_init(void) +{ + if (!kvm_para_available()) + return; + + paravirt_ops_setup(); +} diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 3ef92a2..65f3a23 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c @@ -782,6 +782,7 @@ void __init setup_arch(char **cmdline_p) */ vmi_init(); #endif + kvm_guest_init(); /* * NOTE: before this point _nobody_ is allowed to allocate diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 26b676f..10a8ff5 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c @@ -452,6 +452,8 @@ void __init setup_arch(char **cmdline_p) init_apic_mappings(); ioapic_init_mappings(); + kvm_guest_init(); + /* * We trust e820 completely. No explicit ROM probing in memory. */ diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index 5497aac..9c462c9 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h @@ -20,6 +20,12 @@ #include asm/kvm_para.h #ifdef __KERNEL__ +#ifdef CONFIG_KVM_GUEST +void __init kvm_guest_init(void); +#else +#define kvm_guest_init() do { } while (0) +#endif + static inline int kvm_para_has_feature(unsigned int feature) { if (kvm_arch_para_features() (1UL feature)) -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 12/35] KVM: replace remaining __FUNCTION__ occurances
From: Harvey Harrison [EMAIL PROTECTED] __FUNCTION__ is gcc-specific, use __func__ Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/lapic.c |8 arch/x86/kvm/mmu.c | 35 +-- arch/x86/kvm/paging_tmpl.h | 14 +++--- arch/x86/kvm/svm.c | 14 +++--- arch/x86/kvm/vmx.c |6 +++--- arch/x86/kvm/x86.c | 12 ++-- 6 files changed, 44 insertions(+), 45 deletions(-) diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 68a6b15..31280df 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -658,7 +658,7 @@ static void start_apic_timer(struct kvm_lapic *apic) apic_debug(%s: bus cycle is % PRId64 ns, now 0x%016 PRIx64 , timer initial count 0x%x, period %lldns, - expire @ 0x%016 PRIx64 .\n, __FUNCTION__, + expire @ 0x%016 PRIx64 .\n, __func__, APIC_BUS_CYCLE_NS, ktime_to_ns(now), apic_get_reg(apic, APIC_TMICT), apic-timer.period, @@ -691,7 +691,7 @@ static void apic_mmio_write(struct kvm_io_device *this, /* too common printing */ if (offset != APIC_EOI) apic_debug(%s: offset 0x%x with length 0x%x, and value is - 0x%x\n, __FUNCTION__, offset, len, val); + 0x%x\n, __func__, offset, len, val); offset = 0xff0; @@ -869,7 +869,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) struct kvm_lapic *apic; int i; - apic_debug(%s\n, __FUNCTION__); + apic_debug(%s\n, __func__); ASSERT(vcpu); apic = vcpu-arch.apic; @@ -907,7 +907,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) apic_update_ppr(apic); apic_debug(KERN_INFO %s: vcpu=%p, id=%d, base_msr= - 0x%016 PRIx64 , base_address=0x%0lx.\n, __FUNCTION__, + 0x%016 PRIx64 , base_address=0x%0lx.\n, __func__, vcpu, kvm_apic_id(apic), vcpu-arch.apic_base, apic-base_address); } diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 1932a3a..414405b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -649,7 +649,7 @@ static int is_empty_shadow_page(u64 *spt) for (pos = spt, end = pos + PAGE_SIZE / sizeof(u64); pos != end; pos++) if (*pos != shadow_trap_nonpresent_pte) { - printk(KERN_ERR %s: %p %llx\n, __FUNCTION__, + printk(KERN_ERR %s: %p %llx\n, __func__, pos, *pos); return 0; } @@ -772,14 +772,14 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) struct kvm_mmu_page *sp; struct hlist_node *node; - pgprintk(%s: looking for gfn %lx\n, __FUNCTION__, gfn); + pgprintk(%s: looking for gfn %lx\n, __func__, gfn); index = kvm_page_table_hashfn(gfn); bucket = kvm-arch.mmu_page_hash[index]; hlist_for_each_entry(sp, node, bucket, hash_link) if (sp-gfn == gfn !sp-role.metaphysical !sp-role.invalid) { pgprintk(%s: found role %x\n, -__FUNCTION__, sp-role.word); +__func__, sp-role.word); return sp; } return NULL; @@ -810,21 +810,21 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, quadrant = (1 ((PT32_PT_BITS - PT64_PT_BITS) * level)) - 1; role.quadrant = quadrant; } - pgprintk(%s: looking gfn %lx role %x\n, __FUNCTION__, + pgprintk(%s: looking gfn %lx role %x\n, __func__, gfn, role.word); index = kvm_page_table_hashfn(gfn); bucket = vcpu-kvm-arch.mmu_page_hash[index]; hlist_for_each_entry(sp, node, bucket, hash_link) if (sp-gfn == gfn sp-role.word == role.word) { mmu_page_add_parent_pte(vcpu, sp, parent_pte); - pgprintk(%s: found\n, __FUNCTION__); + pgprintk(%s: found\n, __func__); return sp; } ++vcpu-kvm-stat.mmu_cache_miss; sp = kvm_mmu_alloc_page(vcpu, parent_pte); if (!sp) return sp; - pgprintk(%s: adding gfn %lx role %x\n, __FUNCTION__, gfn, role.word); + pgprintk(%s: adding gfn %lx role %x\n, __func__, gfn, role.word); sp-gfn = gfn; sp-role = role; hlist_add_head(sp-hash_link, bucket); @@ -960,13 +960,13 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) struct hlist_node *node, *n; int r; - pgprintk(%s: looking for gfn %lx\n
[kvm-devel] [PATCH 18/35] KVM: add basic paravirt support
From: Marcelo Tosatti [EMAIL PROTECTED] Add basic KVM paravirt support. Avoid vm-exits on IO delays. Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |1 + include/asm-x86/kvm_para.h |3 ++- include/linux/kvm.h|1 + 3 files changed, 4 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 621a8e3..1b9e695 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -820,6 +820,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_EXT_CPUID: case KVM_CAP_CLOCKSOURCE: case KVM_CAP_PIT: + case KVM_CAP_NOP_IO_DELAY: r = 1; break; case KVM_CAP_VAPIC: diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h index 5ab7d3d..ed5df3a 100644 --- a/include/asm-x86/kvm_para.h +++ b/include/asm-x86/kvm_para.h @@ -10,7 +10,8 @@ * paravirtualization, the appropriate feature bit should be checked. */ #define KVM_CPUID_FEATURES 0x4001 -#define KVM_FEATURE_CLOCKSOURCE 0 +#define KVM_FEATURE_CLOCKSOURCE0 +#define KVM_FEATURE_NOP_IO_DELAY 1 #define MSR_KVM_WALL_CLOCK 0x11 #define MSR_KVM_SYSTEM_TIME 0x12 diff --git a/include/linux/kvm.h b/include/linux/kvm.h index a2f3274..76f0947 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -237,6 +237,7 @@ struct kvm_vapic_addr { #define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ #define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ #define KVM_CAP_PIT 11 +#define KVM_CAP_NOP_IO_DELAY 12 /* * ioctls for VM fds -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 25/35] x86: make native_machine_shutdown non-static
From: Glauber Costa [EMAIL PROTECTED] it will allow external users to call it. It is mainly useful for routines that will override its machine_ops field for its own special purposes, but want to call the normal shutdown routine after they're done Signed-off-by: Glauber Costa [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kernel/reboot.c |2 +- include/asm-x86/reboot.h |1 + 2 files changed, 2 insertions(+), 1 deletions(-) diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 708d6f8..1481d85 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -400,7 +400,7 @@ static void native_machine_emergency_restart(void) } } -static void native_machine_shutdown(void) +void native_machine_shutdown(void) { /* Stop the cpus and apics */ #ifdef CONFIG_SMP diff --git a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h index ff9b546..c5e8722 100644 --- a/include/asm-x86/reboot.h +++ b/include/asm-x86/reboot.h @@ -17,5 +17,6 @@ extern struct machine_ops machine_ops; void machine_real_restart(unsigned char *code, int length); void native_machine_crash_shutdown(struct pt_regs *regs); +void native_machine_shutdown(void); #endif /* _ASM_REBOOT_H */ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 15/35] KVM: In kernel PIT model
From: Sheng Yang [EMAIL PROTECTED] The patch moved PIT from userspace to kernel, and increase the timer accuracy greatly. Signed-off-by: Sheng Yang [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/Makefile |3 +- arch/x86/kvm/i8254.c | 585 arch/x86/kvm/i8254.h | 60 + arch/x86/kvm/irq.c |3 + arch/x86/kvm/x86.c |9 + include/asm-x86/kvm_host.h |1 + include/linux/kvm.h|2 + 7 files changed, 662 insertions(+), 1 deletions(-) create mode 100644 arch/x86/kvm/i8254.c create mode 100644 arch/x86/kvm/i8254.h diff --git a/arch/x86/kvm/Makefile b/arch/x86/kvm/Makefile index ffdd0b3..4d0c22e 100644 --- a/arch/x86/kvm/Makefile +++ b/arch/x86/kvm/Makefile @@ -6,7 +6,8 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o) EXTRA_CFLAGS += -Ivirt/kvm -Iarch/x86/kvm -kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o +kvm-objs := $(common-objs) x86.o mmu.o x86_emulate.o i8259.o irq.o lapic.o \ + i8254.o obj-$(CONFIG_KVM) += kvm.o kvm-intel-objs = vmx.o obj-$(CONFIG_KVM_INTEL) += kvm-intel.o diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c new file mode 100644 index 000..1031901 --- /dev/null +++ b/arch/x86/kvm/i8254.c @@ -0,0 +1,585 @@ +/* + * 8253/8254 interval timer emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2006 Intel Corporation + * Copyright (c) 2007 Keir Fraser, XenSource Inc + * Copyright (c) 2008 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the Software), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Authors: + * Sheng Yang [EMAIL PROTECTED] + * Based on QEMU and Xen. + */ + +#include linux/kvm_host.h + +#include irq.h +#include i8254.h + +#ifndef CONFIG_X86_64 +#define mod_64(x, y) ((x) - (y) * div64_64(x, y)) +#else +#define mod_64(x, y) ((x) % (y)) +#endif + +#define RW_STATE_LSB 1 +#define RW_STATE_MSB 2 +#define RW_STATE_WORD0 3 +#define RW_STATE_WORD1 4 + +/* Compute with 96 bit intermediate result: (a*b)/c */ +static u64 muldiv64(u64 a, u32 b, u32 c) +{ + union { + u64 ll; + struct { + u32 low, high; + } l; + } u, res; + u64 rl, rh; + + u.ll = a; + rl = (u64)u.l.low * (u64)b; + rh = (u64)u.l.high * (u64)b; + rh += (rl 32); + res.l.high = div64_64(rh, c); + res.l.low = div64_64(((mod_64(rh, c) 32) + (rl 0x)), c); + return res.ll; +} + +static void pit_set_gate(struct kvm *kvm, int channel, u32 val) +{ + struct kvm_kpit_channel_state *c = + kvm-arch.vpit-pit_state.channels[channel]; + + WARN_ON(!mutex_is_locked(kvm-arch.vpit-pit_state.lock)); + + switch (c-mode) { + default: + case 0: + case 4: + /* XXX: just disable/enable counting */ + break; + case 1: + case 2: + case 3: + case 5: + /* Restart counting on rising edge. */ + if (c-gate val) + c-count_load_time = ktime_get(); + break; + } + + c-gate = val; +} + +int pit_get_gate(struct kvm *kvm, int channel) +{ + WARN_ON(!mutex_is_locked(kvm-arch.vpit-pit_state.lock)); + + return kvm-arch.vpit-pit_state.channels[channel].gate; +} + +static int pit_get_count(struct kvm *kvm, int channel) +{ + struct kvm_kpit_channel_state *c = + kvm-arch.vpit-pit_state.channels[channel]; + s64 d, t; + int counter; + + WARN_ON(!mutex_is_locked(kvm-arch.vpit-pit_state.lock)); + + t = ktime_to_ns(ktime_sub(ktime_get(), c-count_load_time)); + d = muldiv64(t, KVM_PIT_FREQ, NSEC_PER_SEC); + + switch (c-mode) { + case 0: + case 1: + case 4: + case 5: + counter = (c-count - d) 0x; + break; + case 3
[kvm-devel] [PATCH 22/35] x86: KVM guest: hypercall based pte updates and TLB flushes
From: Marcelo Tosatti [EMAIL PROTECTED] Hypercall based pte updates are faster than faults, and also allow use of the lazy MMU mode to batch operations. Don't report the feature if two dimensional paging is enabled. [avi: - guest/host split - fix 32-bit truncation issues - adjust to mmu_op] Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kernel/kvm.c | 137 + 1 files changed, 137 insertions(+), 0 deletions(-) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index a8e36da..1bb6e97 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -25,6 +25,7 @@ #include linux/kvm_para.h #include linux/cpu.h #include linux/mm.h +#include linux/highmem.h /* * No need for any IO delay on KVM @@ -33,6 +34,122 @@ static void kvm_io_delay(void) { } +static void kvm_mmu_op(void *buffer, unsigned len) +{ + int r; + unsigned long a1, a2; + + do { + a1 = __pa(buffer); + a2 = 0; /* on i386 __pa() always returns 4G */ + r = kvm_hypercall3(KVM_HC_MMU_OP, len, a1, a2); + buffer += r; + len -= r; + } while (len); +} + +static void kvm_mmu_write(void *dest, u64 val) +{ + __u64 pte_phys; + struct kvm_mmu_op_write_pte wpte; + +#ifdef CONFIG_HIGHPTE + struct page *page; + unsigned long dst = (unsigned long) dest; + + page = kmap_atomic_to_page(dest); + pte_phys = page_to_pfn(page); + pte_phys = PAGE_SHIFT; + pte_phys += (dst ~(PAGE_MASK)); +#else + pte_phys = (unsigned long)__pa(dest); +#endif + wpte.header.op = KVM_MMU_OP_WRITE_PTE; + wpte.pte_val = val; + wpte.pte_phys = pte_phys; + + kvm_mmu_op(wpte, sizeof wpte); +} + +/* + * We only need to hook operations that are MMU writes. We hook these so that + * we can use lazy MMU mode to batch these operations. We could probably + * improve the performance of the host code if we used some of the information + * here to simplify processing of batched writes. + */ +static void kvm_set_pte(pte_t *ptep, pte_t pte) +{ + kvm_mmu_write(ptep, pte_val(pte)); +} + +static void kvm_set_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + kvm_mmu_write(ptep, pte_val(pte)); +} + +static void kvm_set_pmd(pmd_t *pmdp, pmd_t pmd) +{ + kvm_mmu_write(pmdp, pmd_val(pmd)); +} + +#if PAGETABLE_LEVELS = 3 +#ifdef CONFIG_X86_PAE +static void kvm_set_pte_atomic(pte_t *ptep, pte_t pte) +{ + kvm_mmu_write(ptep, pte_val(pte)); +} + +static void kvm_set_pte_present(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte) +{ + kvm_mmu_write(ptep, pte_val(pte)); +} + +static void kvm_pte_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + kvm_mmu_write(ptep, 0); +} + +static void kvm_pmd_clear(pmd_t *pmdp) +{ + kvm_mmu_write(pmdp, 0); +} +#endif + +static void kvm_set_pud(pud_t *pudp, pud_t pud) +{ + kvm_mmu_write(pudp, pud_val(pud)); +} + +#if PAGETABLE_LEVELS == 4 +static void kvm_set_pgd(pgd_t *pgdp, pgd_t pgd) +{ + kvm_mmu_write(pgdp, pgd_val(pgd)); +} +#endif +#endif /* PAGETABLE_LEVELS = 3 */ + +static void kvm_flush_tlb(void) +{ + struct kvm_mmu_op_flush_tlb ftlb = { + .header.op = KVM_MMU_OP_FLUSH_TLB, + }; + + kvm_mmu_op(ftlb, sizeof ftlb); +} + +static void kvm_release_pt(u32 pfn) +{ + struct kvm_mmu_op_release_pt rpt = { + .header.op = KVM_MMU_OP_RELEASE_PT, + .pt_phys = (u64)pfn PAGE_SHIFT, + }; + + kvm_mmu_op(rpt, sizeof rpt); +} + static void paravirt_ops_setup(void) { pv_info.name = KVM; @@ -41,6 +158,26 @@ static void paravirt_ops_setup(void) if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) pv_cpu_ops.io_delay = kvm_io_delay; + if (kvm_para_has_feature(KVM_FEATURE_MMU_OP)) { + pv_mmu_ops.set_pte = kvm_set_pte; + pv_mmu_ops.set_pte_at = kvm_set_pte_at; + pv_mmu_ops.set_pmd = kvm_set_pmd; +#if PAGETABLE_LEVELS = 3 +#ifdef CONFIG_X86_PAE + pv_mmu_ops.set_pte_atomic = kvm_set_pte_atomic; + pv_mmu_ops.set_pte_present = kvm_set_pte_present; + pv_mmu_ops.pte_clear = kvm_pte_clear; + pv_mmu_ops.pmd_clear = kvm_pmd_clear; +#endif + pv_mmu_ops.set_pud = kvm_set_pud; +#if PAGETABLE_LEVELS == 4 + pv_mmu_ops.set_pgd = kvm_set_pgd; +#endif +#endif + pv_mmu_ops.flush_tlb_user = kvm_flush_tlb; + pv_mmu_ops.release_pt = kvm_release_pt; + pv_mmu_ops.release_pd = kvm_release_pt; + } } void __init kvm_guest_init(void) -- 1.5.4.5 - Check out the new
[kvm-devel] [PATCH 21/35] KVM: MMU: hypercall based pte updates and TLB flushes
From: Marcelo Tosatti [EMAIL PROTECTED] Hypercall based pte updates are faster than faults, and also allow use of the lazy MMU mode to batch operations. Don't report the feature if two dimensional paging is enabled. [avi: - one mmu_op hypercall instead of one per op - allow 64-bit gpa on hypercall - don't pass host errors (-ENOMEM) to guest] [akpm: warning fix on i386] Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Andrew Morton [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 136 +++- arch/x86/kvm/x86.c | 18 ++- include/asm-x86/kvm_host.h |4 + include/asm-x86/kvm_para.h | 29 + include/linux/kvm.h|1 + include/linux/kvm_para.h |5 +- 6 files changed, 190 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 414405b..072e942 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -28,6 +28,7 @@ #include linux/module.h #include linux/swap.h #include linux/hugetlb.h +#include linux/compiler.h #include asm/page.h #include asm/cmpxchg.h @@ -40,7 +41,7 @@ * 2. while doing 1. it walks guest-physical to host-physical * If the hardware supports that we don't need to do shadow paging. */ -static bool tdp_enabled = false; +bool tdp_enabled = false; #undef MMU_DEBUG @@ -167,6 +168,13 @@ static int dbg = 1; #define ACC_USER_MASKPT_USER_MASK #define ACC_ALL (ACC_EXEC_MASK | ACC_WRITE_MASK | ACC_USER_MASK) +struct kvm_pv_mmu_op_buffer { + void *ptr; + unsigned len; + unsigned processed; + char buf[512] __aligned(sizeof(long)); +}; + struct kvm_rmap_desc { u64 *shadow_ptes[RMAP_EXT]; struct kvm_rmap_desc *more; @@ -2003,6 +2011,132 @@ unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm) return nr_mmu_pages; } +static void *pv_mmu_peek_buffer(struct kvm_pv_mmu_op_buffer *buffer, + unsigned len) +{ + if (len buffer-len) + return NULL; + return buffer-ptr; +} + +static void *pv_mmu_read_buffer(struct kvm_pv_mmu_op_buffer *buffer, + unsigned len) +{ + void *ret; + + ret = pv_mmu_peek_buffer(buffer, len); + if (!ret) + return ret; + buffer-ptr += len; + buffer-len -= len; + buffer-processed += len; + return ret; +} + +static int kvm_pv_mmu_write(struct kvm_vcpu *vcpu, +gpa_t addr, gpa_t value) +{ + int bytes = 8; + int r; + + if (!is_long_mode(vcpu) !is_pae(vcpu)) + bytes = 4; + + r = mmu_topup_memory_caches(vcpu); + if (r) + return r; + + if (!__emulator_write_phys(vcpu, addr, value, bytes)) + return -EFAULT; + + return 1; +} + +static int kvm_pv_mmu_flush_tlb(struct kvm_vcpu *vcpu) +{ + kvm_x86_ops-tlb_flush(vcpu); + return 1; +} + +static int kvm_pv_mmu_release_pt(struct kvm_vcpu *vcpu, gpa_t addr) +{ + spin_lock(vcpu-kvm-mmu_lock); + mmu_unshadow(vcpu-kvm, addr PAGE_SHIFT); + spin_unlock(vcpu-kvm-mmu_lock); + return 1; +} + +static int kvm_pv_mmu_op_one(struct kvm_vcpu *vcpu, +struct kvm_pv_mmu_op_buffer *buffer) +{ + struct kvm_mmu_op_header *header; + + header = pv_mmu_peek_buffer(buffer, sizeof *header); + if (!header) + return 0; + switch (header-op) { + case KVM_MMU_OP_WRITE_PTE: { + struct kvm_mmu_op_write_pte *wpte; + + wpte = pv_mmu_read_buffer(buffer, sizeof *wpte); + if (!wpte) + return 0; + return kvm_pv_mmu_write(vcpu, wpte-pte_phys, + wpte-pte_val); + } + case KVM_MMU_OP_FLUSH_TLB: { + struct kvm_mmu_op_flush_tlb *ftlb; + + ftlb = pv_mmu_read_buffer(buffer, sizeof *ftlb); + if (!ftlb) + return 0; + return kvm_pv_mmu_flush_tlb(vcpu); + } + case KVM_MMU_OP_RELEASE_PT: { + struct kvm_mmu_op_release_pt *rpt; + + rpt = pv_mmu_read_buffer(buffer, sizeof *rpt); + if (!rpt) + return 0; + return kvm_pv_mmu_release_pt(vcpu, rpt-pt_phys); + } + default: return 0; + } +} + +int kvm_pv_mmu_op(struct kvm_vcpu *vcpu, unsigned long bytes, + gpa_t addr, unsigned long *ret) +{ + int r; + struct kvm_pv_mmu_op_buffer buffer; + + down_read(vcpu-kvm-slots_lock); + down_read(current-mm-mmap_sem); + + buffer.ptr = buffer.buf; + buffer.len = min_t(unsigned long, bytes, sizeof buffer.buf); + buffer.processed = 0; + + r = kvm_read_guest(vcpu-kvm, addr, buffer.buf, buffer.len); + if (r) + goto out
[kvm-devel] [PATCH 33/35] KVM: VMX: Add module option to disable flexpriority
Useful for debugging. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/vmx.c |8 ++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index fb0389d..0155931 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -39,6 +39,9 @@ module_param(bypass_guest_pf, bool, 0); static int enable_vpid = 1; module_param(enable_vpid, bool, 0); +static int flexpriority_enabled = 1; +module_param(flexpriority_enabled, bool, 0); + struct vmcs { u32 revision_id; u32 abort; @@ -200,8 +203,9 @@ static inline int cpu_has_secondary_exec_ctrls(void) static inline bool cpu_has_vmx_virtualize_apic_accesses(void) { - return (vmcs_config.cpu_based_2nd_exec_ctrl - SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); + return flexpriority_enabled +(vmcs_config.cpu_based_2nd_exec_ctrl + SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES); } static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 29/35] KVM: Move some x86 specific constants and structures to include/asm-x86
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- include/asm-x86/kvm_host.h | 13 + include/linux/kvm_host.h | 13 - 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 52e276c..2773f91 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -20,6 +20,13 @@ #include asm/desc.h +#define KVM_MAX_VCPUS 16 +#define KVM_MEMORY_SLOTS 32 +/* memory slots that does not exposed to userspace */ +#define KVM_PRIVATE_MEM_SLOTS 4 + +#define KVM_PIO_PAGE_OFFSET 1 + #define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1) #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) ~(X86_CR3_PWT | X86_CR3_PCD)) #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS|0xFF00ULL) @@ -113,6 +120,12 @@ enum { #define KVM_NR_MEM_OBJS 40 +struct kvm_guest_debug { + int enabled; + unsigned long bp[4]; + int singlestep; +}; + /* * We don't want allocation failures within the mmu code, so we preallocate * enough memory for a single page fault in a cache. diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 958e003..f4e1436 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -24,13 +24,6 @@ #include asm/kvm_host.h -#define KVM_MAX_VCPUS 16 -#define KVM_MEMORY_SLOTS 32 -/* memory slots that does not exposed to userspace */ -#define KVM_PRIVATE_MEM_SLOTS 4 - -#define KVM_PIO_PAGE_OFFSET 1 - /* * vcpu-requests bit members */ @@ -43,12 +36,6 @@ struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; -struct kvm_guest_debug { - int enabled; - unsigned long bp[4]; - int singlestep; -}; - /* * It would be nice to use something smarter than a linear search, TBD... * Thankfully we dont expect many devices to register (famous last words :), -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 31/35] KVM: MMU: Introduce and use spte_to_page()
Encapsulate the pte mask'n'shift in a function. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 17 - 1 files changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index dd4b95b..6fc3421 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -240,6 +240,13 @@ static int is_rmap_pte(u64 pte) return is_shadow_present_pte(pte); } +static struct page *spte_to_page(u64 pte) +{ + hfn_t hfn = (pte PT64_BASE_ADDR_MASK) PAGE_SHIFT; + + return pfn_to_page(hfn); +} + static gfn_t pse36_gfn_delta(u32 gpte) { int shift = 32 - PT32_DIR_PSE36_SHIFT - PAGE_SHIFT; @@ -541,7 +548,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) if (!is_rmap_pte(*spte)) return; sp = page_header(__pa(spte)); - page = pfn_to_page((*spte PT64_BASE_ADDR_MASK) PAGE_SHIFT); + page = spte_to_page(*spte); mark_page_accessed(page); if (is_writeble_pte(*spte)) kvm_release_page_dirty(page); @@ -630,7 +637,7 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn) struct page *page; spte = rmap_next(kvm, rmapp, NULL); - page = pfn_to_page((*spte PT64_BASE_ADDR_MASK) PAGE_SHIFT); + page = spte_to_page(*spte); SetPageDirty(page); } @@ -1033,7 +1040,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, u64 spte; int was_rmapped = 0; int was_writeble = is_writeble_pte(*shadow_pte); - hfn_t host_pfn = (*shadow_pte PT64_BASE_ADDR_MASK) PAGE_SHIFT; pgprintk(%s: spte %llx access %x write_fault %d user_fault %d gfn %lx\n, @@ -1051,9 +1057,10 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, child = page_header(pte PT64_BASE_ADDR_MASK); mmu_page_remove_parent_pte(child, shadow_pte); - } else if (host_pfn != page_to_pfn(page)) { + } else if (page != spte_to_page(*shadow_pte)) { pgprintk(hfn old %lx new %lx\n, -host_pfn, page_to_pfn(page)); +page_to_pfn(spte_to_page(*shadow_pte)), +page_to_pfn(page)); rmap_remove(vcpu-kvm, shadow_pte); } else { if (largepage) -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 32/35] KVM: no longer EXPERIMENTAL
Long overdue. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/Kconfig |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 41962e7..76c70ab 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -19,7 +19,7 @@ if VIRTUALIZATION config KVM tristate Kernel-based Virtual Machine (KVM) support - depends on HAVE_KVM EXPERIMENTAL + depends on HAVE_KVM select PREEMPT_NOTIFIERS select ANON_INODES ---help--- -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 28/35] KVM: MMU: Set the accessed bit on non-speculative shadow ptes
If we populate a shadow pte due to a fault (and not speculatively due to a pte write) then we can set the accessed bit on it, as we know it will be set immediately on the next guest instruction. This saves a read-modify-write operation. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c |8 +--- arch/x86/kvm/paging_tmpl.h |4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 072e942..a5872b3 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -1020,7 +1020,7 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, unsigned pt_access, unsigned pte_access, int user_fault, int write_fault, int dirty, int *ptwrite, int largepage, gfn_t gfn, -struct page *page) +struct page *page, bool speculative) { u64 spte; int was_rmapped = 0; @@ -1061,6 +1061,8 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, * demand paging). */ spte = PT_PRESENT_MASK | PT_DIRTY_MASK; + if (!speculative) + pte_access |= PT_ACCESSED_MASK; if (!dirty) pte_access = ~ACC_WRITE_MASK; if (!(pte_access ACC_EXEC_MASK)) @@ -1148,13 +1150,13 @@ static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, if (level == 1) { mmu_set_spte(vcpu, table[index], ACC_ALL, ACC_ALL, -0, write, 1, pt_write, 0, gfn, page); +0, write, 1, pt_write, 0, gfn, page, false); return pt_write; } if (largepage level == 2) { mmu_set_spte(vcpu, table[index], ACC_ALL, ACC_ALL, - 0, write, 1, pt_write, 1, gfn, page); +0, write, 1, pt_write, 1, gfn, page, false); return pt_write; } diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index 57abbd0..e9ae5db 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -266,7 +266,7 @@ static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *page, get_page(npage); mmu_set_spte(vcpu, spte, page-role.access, pte_access, 0, 0, gpte PT_DIRTY_MASK, NULL, largepage, gpte_to_gfn(gpte), -npage); +npage, true); } /* @@ -349,7 +349,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, mmu_set_spte(vcpu, shadow_ent, access, walker-pte_access access, user_fault, write_fault, walker-ptes[walker-level-1] PT_DIRTY_MASK, -ptwrite, largepage, walker-gfn, page); +ptwrite, largepage, walker-gfn, page, false); return shadow_ent; } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 30/35] KVM: MMU: fix dirty bit setting when removing write permissions
From: Izik Eidus [EMAIL PROTECTED] When mmu_set_spte() checks if a page related to spte should be release as dirty or clean, it check if the shadow pte was writeble, but in case rmap_write_protect() is called called it is possible for shadow ptes that were writeble to become readonly and therefor mmu_set_spte will release the pages as clean. This patch fix this issue by marking the page as dirty inside rmap_write_protect(). Signed-off-by: Izik Eidus [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index a5872b3..dd4b95b 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -626,6 +626,14 @@ static void rmap_write_protect(struct kvm *kvm, u64 gfn) } spte = rmap_next(kvm, rmapp, spte); } + if (write_protected) { + struct page *page; + + spte = rmap_next(kvm, rmapp, NULL); + page = pfn_to_page((*spte PT64_BASE_ADDR_MASK) PAGE_SHIFT); + SetPageDirty(page); + } + /* check for huge page mappings */ rmapp = gfn_to_rmap(kvm, gfn, 1); spte = rmap_next(kvm, rmapp, NULL); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 26/35] x86: KVM guest: disable clock before rebooting.
From: Glauber Costa [EMAIL PROTECTED] This patch writes 0 (actually, what really matters is that the LSB is cleared) to the system time msr before shutting down the machine for kexec. Without it, we can have a random memory location being written when the guest comes back It overrides the functions shutdown, used in the path of kernel_kexec() (sys.c) and crash_shutdown, used in the path of crash_kexec() (kexec.c) Signed-off-by: Glauber Costa [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kernel/kvmclock.c | 27 +++ 1 files changed, 27 insertions(+), 0 deletions(-) diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c index b999f5e..ddee040 100644 --- a/arch/x86/kernel/kvmclock.c +++ b/arch/x86/kernel/kvmclock.c @@ -22,6 +22,7 @@ #include asm/msr.h #include asm/apic.h #include linux/percpu.h +#include asm/reboot.h #define KVM_SCALE 22 @@ -143,6 +144,28 @@ static void kvm_setup_secondary_clock(void) setup_secondary_APIC_clock(); } +/* + * After the clock is registered, the host will keep writing to the + * registered memory location. If the guest happens to shutdown, this memory + * won't be valid. In cases like kexec, in which you install a new kernel, this + * means a random memory location will be kept being written. So before any + * kind of shutdown from our side, we unregister the clock by writting anything + * that does not have the 'enable' bit set in the msr + */ +#ifdef CONFIG_KEXEC +static void kvm_crash_shutdown(struct pt_regs *regs) +{ + native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); + native_machine_crash_shutdown(regs); +} +#endif + +static void kvm_shutdown(void) +{ + native_write_msr_safe(MSR_KVM_SYSTEM_TIME, 0, 0); + native_machine_shutdown(); +} + void __init kvmclock_init(void) { if (!kvm_para_available()) @@ -155,6 +178,10 @@ void __init kvmclock_init(void) pv_time_ops.set_wallclock = kvm_set_wallclock; pv_time_ops.sched_clock = kvm_clock_read; pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock; + machine_ops.shutdown = kvm_shutdown; +#ifdef CONFIG_KEXEC + machine_ops.crash_shutdown = kvm_crash_shutdown; +#endif clocksource_register(kvm_clock); } } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 08/35] KVM: MMU: large page support
From: Marcelo Tosatti [EMAIL PROTECTED] Create large pages mappings if the guest PTE's are marked as such and the underlying memory is hugetlbfs backed. If the largepage contains write-protected pages, a large pte is not used. Gives a consistent 2% improvement for data copies on ram mounted filesystem, without NPT/EPT. Anthony measures a 4% improvement on 4-way kernbench, with NPT. Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 222 +++- arch/x86/kvm/paging_tmpl.h | 32 +- arch/x86/kvm/x86.c |1 + include/asm-x86/kvm_host.h |9 ++ include/linux/kvm_host.h |5 + virt/kvm/kvm_main.c| 22 - 6 files changed, 259 insertions(+), 32 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 103d008..1932a3a 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -27,6 +27,7 @@ #include linux/highmem.h #include linux/module.h #include linux/swap.h +#include linux/hugetlb.h #include asm/page.h #include asm/cmpxchg.h @@ -211,6 +212,11 @@ static int is_shadow_present_pte(u64 pte) pte != shadow_notrap_nonpresent_pte; } +static int is_large_pte(u64 pte) +{ + return pte PT_PAGE_SIZE_MASK; +} + static int is_writeble_pte(unsigned long pte) { return pte PT_WRITABLE_MASK; @@ -350,16 +356,100 @@ static void mmu_free_rmap_desc(struct kvm_rmap_desc *rd) } /* + * Return the pointer to the largepage write count for a given + * gfn, handling slots that are not large page aligned. + */ +static int *slot_largepage_idx(gfn_t gfn, struct kvm_memory_slot *slot) +{ + unsigned long idx; + + idx = (gfn / KVM_PAGES_PER_HPAGE) - + (slot-base_gfn / KVM_PAGES_PER_HPAGE); + return slot-lpage_info[idx].write_count; +} + +static void account_shadowed(struct kvm *kvm, gfn_t gfn) +{ + int *write_count; + + write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn)); + *write_count += 1; + WARN_ON(*write_count KVM_PAGES_PER_HPAGE); +} + +static void unaccount_shadowed(struct kvm *kvm, gfn_t gfn) +{ + int *write_count; + + write_count = slot_largepage_idx(gfn, gfn_to_memslot(kvm, gfn)); + *write_count -= 1; + WARN_ON(*write_count 0); +} + +static int has_wrprotected_page(struct kvm *kvm, gfn_t gfn) +{ + struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); + int *largepage_idx; + + if (slot) { + largepage_idx = slot_largepage_idx(gfn, slot); + return *largepage_idx; + } + + return 1; +} + +static int host_largepage_backed(struct kvm *kvm, gfn_t gfn) +{ + struct vm_area_struct *vma; + unsigned long addr; + + addr = gfn_to_hva(kvm, gfn); + if (kvm_is_error_hva(addr)) + return 0; + + vma = find_vma(current-mm, addr); + if (vma is_vm_hugetlb_page(vma)) + return 1; + + return 0; +} + +static int is_largepage_backed(struct kvm_vcpu *vcpu, gfn_t large_gfn) +{ + struct kvm_memory_slot *slot; + + if (has_wrprotected_page(vcpu-kvm, large_gfn)) + return 0; + + if (!host_largepage_backed(vcpu-kvm, large_gfn)) + return 0; + + slot = gfn_to_memslot(vcpu-kvm, large_gfn); + if (slot slot-dirty_bitmap) + return 0; + + return 1; +} + +/* * Take gfn and return the reverse mapping to it. * Note: gfn must be unaliased before this function get called */ -static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn) +static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn, int lpage) { struct kvm_memory_slot *slot; + unsigned long idx; slot = gfn_to_memslot(kvm, gfn); - return slot-rmap[gfn - slot-base_gfn]; + if (!lpage) + return slot-rmap[gfn - slot-base_gfn]; + + idx = (gfn / KVM_PAGES_PER_HPAGE) - + (slot-base_gfn / KVM_PAGES_PER_HPAGE); + + return slot-lpage_info[idx].rmap_pde; } /* @@ -371,7 +461,7 @@ static unsigned long *gfn_to_rmap(struct kvm *kvm, gfn_t gfn) * If rmapp bit zero is one, (then rmap ~1) points to a struct kvm_rmap_desc * containing more mappings. */ -static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) +static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn, int lpage) { struct kvm_mmu_page *sp; struct kvm_rmap_desc *desc; @@ -383,7 +473,7 @@ static void rmap_add(struct kvm_vcpu *vcpu, u64 *spte, gfn_t gfn) gfn = unalias_gfn(vcpu-kvm, gfn); sp = page_header(__pa(spte)); sp-gfns[spte - sp-spt] = gfn; - rmapp = gfn_to_rmap(vcpu-kvm, gfn); + rmapp = gfn_to_rmap(vcpu-kvm, gfn, lpage); if (!*rmapp) { rmap_printk(rmap_add: %p %llx 0-1\n, spte, *spte); *rmapp = (unsigned long)spte; @@ -449,7 +539,7 @@ static void
[kvm-devel] [PATCH 34/35] KVM: x86: add functions to get the cpl of vcpu
From: Izik Eidus [EMAIL PROTECTED] Signed-off-by: Izik Eidus [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |8 arch/x86/kvm/vmx.c | 15 +++ include/asm-x86/kvm_host.h |1 + 3 files changed, 24 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 51741f9..c1c1b97 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -792,6 +792,13 @@ static void svm_get_segment(struct kvm_vcpu *vcpu, var-unusable = !var-present; } +static int svm_get_cpl(struct kvm_vcpu *vcpu) +{ + struct vmcb_save_area *save = to_svm(vcpu)-vmcb-save; + + return save-cpl; +} + static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) { struct vcpu_svm *svm = to_svm(vcpu); @@ -1822,6 +1829,7 @@ static struct kvm_x86_ops svm_x86_ops = { .get_segment_base = svm_get_segment_base, .get_segment = svm_get_segment, .set_segment = svm_set_segment, + .get_cpl = svm_get_cpl, .get_cs_db_l_bits = kvm_get_cs_db_l_bits, .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, .set_cr0 = svm_set_cr0, diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 0155931..9b56032 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1395,6 +1395,20 @@ static void vmx_get_segment(struct kvm_vcpu *vcpu, var-unusable = (ar 16) 1; } +static int vmx_get_cpl(struct kvm_vcpu *vcpu) +{ + struct kvm_segment kvm_seg; + + if (!(vcpu-arch.cr0 X86_CR0_PE)) /* if real mode */ + return 0; + + if (vmx_get_rflags(vcpu) X86_EFLAGS_VM) /* if virtual 8086 */ + return 3; + + vmx_get_segment(vcpu, kvm_seg, VCPU_SREG_CS); + return kvm_seg.selector 3; +} + static u32 vmx_segment_access_rights(struct kvm_segment *var) { u32 ar; @@ -2665,6 +2679,7 @@ static struct kvm_x86_ops vmx_x86_ops = { .get_segment_base = vmx_get_segment_base, .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, + .get_cpl = vmx_get_cpl, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, .decache_cr4_guest_bits = vmx_decache_cr4_guest_bits, .set_cr0 = vmx_set_cr0, diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 2773f91..06bd154 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -387,6 +387,7 @@ struct kvm_x86_ops { u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg); void (*get_segment)(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); + int (*get_cpl)(struct kvm_vcpu *vcpu); void (*set_segment)(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg); void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu, int *db, int *l); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 35/35] KVM: x86: hardware task switching support
From: Izik Eidus [EMAIL PROTECTED] This emulates the x86 hardware task switch mechanism in software, as it is unsupported by either vmx or svm. It allows operating systems which use it, like freedos, to run as kvm guests. Signed-off-by: Izik Eidus [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c | 15 ++- arch/x86/kvm/svm.h |3 + arch/x86/kvm/tss.h | 59 +++ arch/x86/kvm/vmx.c | 15 ++ arch/x86/kvm/x86.c | 408 include/asm-x86/kvm_host.h |9 + 6 files changed, 506 insertions(+), 3 deletions(-) create mode 100644 arch/x86/kvm/tss.h diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c1c1b97..ad27346 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1112,9 +1112,18 @@ static int invalid_op_interception(struct vcpu_svm *svm, static int task_switch_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) { - pr_unimpl(svm-vcpu, %s: task switch is unsupported\n, __func__); - kvm_run-exit_reason = KVM_EXIT_UNKNOWN; - return 0; + u16 tss_selector; + + tss_selector = (u16)svm-vmcb-control.exit_info_1; + if (svm-vmcb-control.exit_info_2 + (1ULL SVM_EXITINFOSHIFT_TS_REASON_IRET)) + return kvm_task_switch(svm-vcpu, tss_selector, + TASK_SWITCH_IRET); + if (svm-vmcb-control.exit_info_2 + (1ULL SVM_EXITINFOSHIFT_TS_REASON_JMP)) + return kvm_task_switch(svm-vcpu, tss_selector, + TASK_SWITCH_JMP); + return kvm_task_switch(svm-vcpu, tss_selector, TASK_SWITCH_CALL); } static int cpuid_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) diff --git a/arch/x86/kvm/svm.h b/arch/x86/kvm/svm.h index 5fd5049..1b8afa7 100644 --- a/arch/x86/kvm/svm.h +++ b/arch/x86/kvm/svm.h @@ -238,6 +238,9 @@ struct __attribute__ ((__packed__)) vmcb { #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR +#define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 +#define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 + #defineSVM_EXIT_READ_CR0 0x000 #defineSVM_EXIT_READ_CR3 0x003 #defineSVM_EXIT_READ_CR4 0x004 diff --git a/arch/x86/kvm/tss.h b/arch/x86/kvm/tss.h new file mode 100644 index 000..622aa10 --- /dev/null +++ b/arch/x86/kvm/tss.h @@ -0,0 +1,59 @@ +#ifndef __TSS_SEGMENT_H +#define __TSS_SEGMENT_H + +struct tss_segment_32 { + u32 prev_task_link; + u32 esp0; + u32 ss0; + u32 esp1; + u32 ss1; + u32 esp2; + u32 ss2; + u32 cr3; + u32 eip; + u32 eflags; + u32 eax; + u32 ecx; + u32 edx; + u32 ebx; + u32 esp; + u32 ebp; + u32 esi; + u32 edi; + u32 es; + u32 cs; + u32 ss; + u32 ds; + u32 fs; + u32 gs; + u32 ldt_selector; + u16 t; + u16 io_map; +}; + +struct tss_segment_16 { + u16 prev_task_link; + u16 sp0; + u16 ss0; + u16 sp1; + u16 ss1; + u16 sp2; + u16 ss2; + u16 ip; + u16 flag; + u16 ax; + u16 cx; + u16 dx; + u16 bx; + u16 sp; + u16 bp; + u16 si; + u16 di; + u16 es; + u16 cs; + u16 ss; + u16 ds; + u16 ldt; +}; + +#endif diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 9b56032..cbca46a 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -2249,6 +2249,20 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; } +static int handle_task_switch(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) +{ + unsigned long exit_qualification; + u16 tss_selector; + int reason; + + exit_qualification = vmcs_readl(EXIT_QUALIFICATION); + + reason = (u32)exit_qualification 30; + tss_selector = exit_qualification; + + return kvm_task_switch(vcpu, tss_selector, reason); +} + /* * The exit handlers return 1 if the exit was handled fully and guest execution * may resume. Otherwise they set the kvm_run parameter to indicate what needs @@ -2271,6 +2285,7 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu, [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, [EXIT_REASON_APIC_ACCESS] = handle_apic_access, [EXIT_REASON_WBINVD] = handle_wbinvd, + [EXIT_REASON_TASK_SWITCH] = handle_task_switch, }; static const int kvm_vmx_max_exit_handlers = diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 63afca1..acecde4 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -18,6 +18,7 @@ #include irq.h #include mmu.h #include i8254.h +#include tss.h #include linux/clocksource.h #include linux/kvm.h
[kvm-devel] [PATCH 24/35] x86: allow machine_crash_shutdown to be replaced
From: Glauber Costa [EMAIL PROTECTED] This patch a llows machine_crash_shutdown to be replaced, just like any of the other functions in machine_ops Signed-off-by: Glauber Costa [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kernel/crash.c |3 ++- arch/x86/kernel/reboot.c | 11 ++- include/asm-x86/reboot.h |1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c index 9a5fa0a..d262306 100644 --- a/arch/x86/kernel/crash.c +++ b/arch/x86/kernel/crash.c @@ -25,6 +25,7 @@ #include asm/hpet.h #include linux/kdebug.h #include asm/smp.h +#include asm/reboot.h #ifdef CONFIG_X86_32 #include mach_ipi.h @@ -121,7 +122,7 @@ static void nmi_shootdown_cpus(void) } #endif -void machine_crash_shutdown(struct pt_regs *regs) +void native_machine_crash_shutdown(struct pt_regs *regs) { /* This function is only called after the system * has panicked or is otherwise in a critical state. diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 484c4a8..708d6f8 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -471,7 +471,10 @@ struct machine_ops machine_ops = { .shutdown = native_machine_shutdown, .emergency_restart = native_machine_emergency_restart, .restart = native_machine_restart, - .halt = native_machine_halt + .halt = native_machine_halt, +#ifdef CONFIG_KEXEC + .crash_shutdown = native_machine_crash_shutdown, +#endif }; void machine_power_off(void) @@ -499,3 +502,9 @@ void machine_halt(void) machine_ops.halt(); } +#ifdef CONFIG_KEXEC +void machine_crash_shutdown(struct pt_regs *regs) +{ + machine_ops.crash_shutdown(regs); +} +#endif diff --git a/include/asm-x86/reboot.h b/include/asm-x86/reboot.h index e9e3ffc..ff9b546 100644 --- a/include/asm-x86/reboot.h +++ b/include/asm-x86/reboot.h @@ -16,5 +16,6 @@ struct machine_ops extern struct machine_ops machine_ops; void machine_real_restart(unsigned char *code, int length); +void native_machine_crash_shutdown(struct pt_regs *regs); #endif /* _ASM_REBOOT_H */ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 09/35] KVM: Prefix control register accessors with kvm_ to avoid namespace pollution
Names like 'set_cr3()' look dangerously close to affecting the host. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/vmx.c | 14 ++-- arch/x86/kvm/x86.c | 46 ++-- include/asm-x86/kvm_host.h | 12 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index f46ad03..5034503 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1683,7 +1683,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) vmx-vcpu.arch.rmode.active = 0; vmx-vcpu.arch.regs[VCPU_REGS_RDX] = get_rdx_init_val(); - set_cr8(vmx-vcpu, 0); + kvm_set_cr8(vmx-vcpu, 0); msr = 0xfee0 | MSR_IA32_APICBASE_ENABLE; if (vmx-vcpu.vcpu_id == 0) msr |= MSR_IA32_APICBASE_BSP; @@ -2026,22 +2026,22 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) switch (cr) { case 0: vcpu_load_rsp_rip(vcpu); - set_cr0(vcpu, vcpu-arch.regs[reg]); + kvm_set_cr0(vcpu, vcpu-arch.regs[reg]); skip_emulated_instruction(vcpu); return 1; case 3: vcpu_load_rsp_rip(vcpu); - set_cr3(vcpu, vcpu-arch.regs[reg]); + kvm_set_cr3(vcpu, vcpu-arch.regs[reg]); skip_emulated_instruction(vcpu); return 1; case 4: vcpu_load_rsp_rip(vcpu); - set_cr4(vcpu, vcpu-arch.regs[reg]); + kvm_set_cr4(vcpu, vcpu-arch.regs[reg]); skip_emulated_instruction(vcpu); return 1; case 8: vcpu_load_rsp_rip(vcpu); - set_cr8(vcpu, vcpu-arch.regs[reg]); + kvm_set_cr8(vcpu, vcpu-arch.regs[reg]); skip_emulated_instruction(vcpu); if (irqchip_in_kernel(vcpu-kvm)) return 1; @@ -2067,14 +2067,14 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) return 1; case 8: vcpu_load_rsp_rip(vcpu); - vcpu-arch.regs[reg] = get_cr8(vcpu); + vcpu-arch.regs[reg] = kvm_get_cr8(vcpu); vcpu_put_rsp_rip(vcpu); skip_emulated_instruction(vcpu); return 1; } break; case 3: /* lmsw */ - lmsw(vcpu, (exit_qualification LMSW_SOURCE_DATA_SHIFT) 0x0f); + kvm_lmsw(vcpu, (exit_qualification LMSW_SOURCE_DATA_SHIFT) 0x0f); skip_emulated_instruction(vcpu); return 1; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0458bd5..dbcff38 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -237,7 +237,7 @@ out: return changed; } -void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) +void kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) { if (cr0 CR0_RESERVED_BITS) { printk(KERN_DEBUG set_cr0: 0x%lx #GP, reserved bits 0x%lx\n, @@ -295,15 +295,15 @@ void set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) kvm_mmu_reset_context(vcpu); return; } -EXPORT_SYMBOL_GPL(set_cr0); +EXPORT_SYMBOL_GPL(kvm_set_cr0); -void lmsw(struct kvm_vcpu *vcpu, unsigned long msw) +void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) { - set_cr0(vcpu, (vcpu-arch.cr0 ~0x0ful) | (msw 0x0f)); + kvm_set_cr0(vcpu, (vcpu-arch.cr0 ~0x0ful) | (msw 0x0f)); } -EXPORT_SYMBOL_GPL(lmsw); +EXPORT_SYMBOL_GPL(kvm_lmsw); -void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) +void kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { if (cr4 CR4_RESERVED_BITS) { printk(KERN_DEBUG set_cr4: #GP, reserved bits\n); @@ -334,9 +334,9 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) vcpu-arch.cr4 = cr4; kvm_mmu_reset_context(vcpu); } -EXPORT_SYMBOL_GPL(set_cr4); +EXPORT_SYMBOL_GPL(kvm_set_cr4); -void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) +void kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { if (cr3 == vcpu-arch.cr3 !pdptrs_changed(vcpu)) { kvm_mmu_flush_tlb(vcpu); @@ -388,9 +388,9 @@ void set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) } up_read(vcpu-kvm-slots_lock); } -EXPORT_SYMBOL_GPL(set_cr3); +EXPORT_SYMBOL_GPL(kvm_set_cr3); -void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) +void kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8) { if (cr8 CR8_RESERVED_BITS) { printk(KERN_DEBUG set_cr8: #GP, reserved bits 0x%lx\n, cr8); @@ -402,16 +402,16 @@ void
[kvm-devel] [PATCH 27/35] KVM: kvm.h: __user requires compiler.h
From: Christian Borntraeger [EMAIL PROTECTED] include/linux/kvm.h defines struct kvm_dirty_log to [...] union { void __user *dirty_bitmap; /* one bit per page */ __u64 padding; }; __user requires compiler.h to compile. Currently, this works on x86 only coincidentally due to other include files. This patch makes kvm.h compile in all cases. Signed-off-by: Christian Borntraeger [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- include/linux/kvm.h |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/include/linux/kvm.h b/include/linux/kvm.h index c1b502a..3bd3828 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -8,6 +8,7 @@ */ #include asm/types.h +#include linux/compiler.h #include linux/ioctl.h #include asm/kvm.h -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 07/35] KVM: MMU: ignore zapped root pagetables
From: Marcelo Tosatti [EMAIL PROTECTED] Mark zapped root pagetables as invalid and ignore such pages during lookup. This is a problem with the cr3-target feature, where a zapped root table fools the faulting code into creating a read-only mapping. The result is a lockup if the instruction can't be emulated. Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Cc: Anthony Liguori [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 12 ++-- arch/x86/kvm/x86.c | 12 include/asm-x86/kvm_host.h |1 + include/linux/kvm_host.h |2 ++ virt/kvm/kvm_main.c| 23 +++ 5 files changed, 48 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index f7541fe..103d008 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -667,7 +667,8 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) index = kvm_page_table_hashfn(gfn); bucket = kvm-arch.mmu_page_hash[index]; hlist_for_each_entry(sp, node, bucket, hash_link) - if (sp-gfn == gfn !sp-role.metaphysical) { + if (sp-gfn == gfn !sp-role.metaphysical +!sp-role.invalid) { pgprintk(%s: found role %x\n, __FUNCTION__, sp-role.word); return sp; @@ -792,8 +793,11 @@ static void kvm_mmu_zap_page(struct kvm *kvm, struct kvm_mmu_page *sp) if (!sp-root_count) { hlist_del(sp-hash_link); kvm_mmu_free_page(kvm, sp); - } else + } else { list_move(sp-link, kvm-arch.active_mmu_pages); + sp-role.invalid = 1; + kvm_reload_remote_mmus(kvm); + } kvm_mmu_reset_last_pte_updated(kvm); } @@ -1073,6 +1077,8 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) sp = page_header(root); --sp-root_count; + if (!sp-root_count sp-role.invalid) + kvm_mmu_zap_page(vcpu-kvm, sp); vcpu-arch.mmu.root_hpa = INVALID_PAGE; spin_unlock(vcpu-kvm-mmu_lock); return; @@ -1085,6 +1091,8 @@ static void mmu_free_roots(struct kvm_vcpu *vcpu) root = PT64_BASE_ADDR_MASK; sp = page_header(root); --sp-root_count; + if (!sp-root_count sp-role.invalid) + kvm_mmu_zap_page(vcpu-kvm, sp); } vcpu-arch.mmu.pae_root[i] = INVALID_PAGE; } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0dd038e..e8e6492 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2658,6 +2658,10 @@ preempted: kvm_x86_ops-guest_debug_pre(vcpu); again: + if (vcpu-requests) + if (test_and_clear_bit(KVM_REQ_MMU_RELOAD, vcpu-requests)) + kvm_mmu_unload(vcpu); + r = kvm_mmu_reload(vcpu); if (unlikely(r)) goto out; @@ -2689,6 +2693,14 @@ again: goto out; } + if (vcpu-requests) + if (test_bit(KVM_REQ_MMU_RELOAD, vcpu-requests)) { + local_irq_enable(); + preempt_enable(); + r = 1; + goto out; + } + if (signal_pending(current)) { local_irq_enable(); preempt_enable(); diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 4f5a71a..7535839 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -140,6 +140,7 @@ union kvm_mmu_page_role { unsigned pad_for_nice_hex_output : 6; unsigned metaphysical : 1; unsigned access : 3; + unsigned invalid : 1; }; }; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index eb88d32..994278f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -37,6 +37,7 @@ #define KVM_REQ_TLB_FLUSH 0 #define KVM_REQ_MIGRATE_TIMER 1 #define KVM_REQ_REPORT_TPR_ACCESS 2 +#define KVM_REQ_MMU_RELOAD 3 struct kvm_vcpu; extern struct kmem_cache *kvm_vcpu_cache; @@ -190,6 +191,7 @@ void kvm_resched(struct kvm_vcpu *vcpu); void kvm_load_guest_fpu(struct kvm_vcpu *vcpu); void kvm_put_guest_fpu(struct kvm_vcpu *vcpu); void kvm_flush_remote_tlbs(struct kvm *kvm); +void kvm_reload_remote_mmus(struct kvm *kvm); long kvm_arch_dev_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cf6df51..c41eb57 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -119,6 +119,29 @@ void kvm_flush_remote_tlbs(struct kvm *kvm) smp_call_function_mask(cpus, ack_flush, NULL, 1); } +void
[kvm-devel] [PATCH 02/35] KVM: Add stat counter for hypercalls
From: Amit Shah [EMAIL PROTECTED] Signed-off-by: Amit Shah [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |2 ++ include/asm-x86/kvm_host.h |1 + 2 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index a063f44..15bba5d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -72,6 +72,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { { irq_window, VCPU_STAT(irq_window_exits) }, { halt_exits, VCPU_STAT(halt_exits) }, { halt_wakeup, VCPU_STAT(halt_wakeup) }, + { hypercalls, VCPU_STAT(hypercalls) }, { request_irq, VCPU_STAT(request_irq_exits) }, { irq_exits, VCPU_STAT(irq_exits) }, { host_state_reload, VCPU_STAT(host_state_reload) }, @@ -2405,6 +2406,7 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) } vcpu-arch.regs[VCPU_REGS_RAX] = ret; kvm_x86_ops-decache_regs(vcpu); + ++vcpu-stat.hypercalls; return 0; } EXPORT_SYMBOL_GPL(kvm_emulate_hypercall); diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 0c429c8..4f5a71a 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -327,6 +327,7 @@ struct kvm_vcpu_stat { u32 fpu_reload; u32 insn_emulation; u32 insn_emulation_fail; + u32 hypercalls; }; struct descriptor_table { -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 00/35] KVM updates for the 2.6.26 merge window (part II)
These thirty-five patches comprise the second batch of the updates I have queued for 2.6.26. Please review. arch/x86/Kconfig |8 + arch/x86/kernel/Makefile |1 + arch/x86/kernel/crash.c |3 +- arch/x86/kernel/kvm.c | 247 ++ arch/x86/kernel/kvmclock.c| 27 ++ arch/x86/kernel/reboot.c | 13 +- arch/x86/kernel/setup_32.c|1 + arch/x86/kernel/setup_64.c|2 + arch/x86/kvm/Kconfig |2 +- arch/x86/kvm/Makefile |3 +- arch/x86/kvm/i8254.c | 600 ++ arch/x86/kvm/i8254.h | 62 arch/x86/kvm/irq.c|3 + arch/x86/kvm/lapic.c |8 +- arch/x86/kvm/mmu.c| 426 ++--- arch/x86/kvm/paging_tmpl.h| 46 ++- arch/x86/kvm/segment_descriptor.h | 29 -- arch/x86/kvm/svm.c| 41 ++- arch/x86/kvm/svm.h|3 + arch/x86/kvm/tss.h| 59 arch/x86/kvm/vmx.c| 70 +++- arch/x86/kvm/x86.c| 647 + arch/x86/kvm/x86_emulate.c|4 +- include/asm-x86/kvm.h | 21 ++ include/asm-x86/kvm_host.h| 54 +++- include/asm-x86/kvm_para.h| 32 ++- include/asm-x86/reboot.h |2 + include/linux/kvm.h |7 + include/linux/kvm_host.h | 21 +- include/linux/kvm_para.h | 11 +- virt/kvm/kvm_main.c | 78 - 31 files changed, 2302 insertions(+), 229 deletions(-) - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 03/35] KVM: x86 emulator: fix sparse warnings in x86_emulate.c
From: Harvey Harrison [EMAIL PROTECTED] Nesting __emulate_2op_nobyte inside__emulate_2op produces many shadowed variable warnings on the internal variable _tmp used by both macros. Change the outer macro to use __tmp. Avoids a sparse warning like the following at every call site of __emulate_2op arch/x86/kvm/x86_emulate.c:1091:3: warning: symbol '_tmp' shadows an earlier one arch/x86/kvm/x86_emulate.c:1091:3: originally declared here [18 more warnings suppressed] Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index cacdcf5..f59ed93 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -371,7 +371,7 @@ static u16 group2_table[] = { #define __emulate_2op(_op,_src,_dst,_eflags,_bx,_by,_wx,_wy,_lx,_ly,_qx,_qy) \ do { \ - unsigned long _tmp; \ + unsigned long __tmp; \ switch ((_dst).bytes) { \ case 1: \ __asm__ __volatile__ ( \ @@ -379,7 +379,7 @@ static u16 group2_table[] = { _opb %_bx3,%1; \ _POST_EFLAGS(0, 4, 2) \ : =m (_eflags), =m ((_dst).val), \ - =r (_tmp) \ + =r (__tmp) \ : _by ((_src).val), i (EFLAGS_MASK)); \ break; \ default: \ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 10/35] KVM: Use kzalloc to avoid allocating kvm_regs from kernel stack
From: Xiantao Zhang [EMAIL PROTECTED] Since the size of kvm_regs is too big to allocate from kernel stack on ia64, use kzalloc to allocate it. Signed-off-by: Xiantao Zhang [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- virt/kvm/kvm_main.c | 33 ++--- 1 files changed, 22 insertions(+), 11 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 0dabf58..30bf832 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -849,28 +849,39 @@ static long kvm_vcpu_ioctl(struct file *filp, r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu-run); break; case KVM_GET_REGS: { - struct kvm_regs kvm_regs; + struct kvm_regs *kvm_regs; - memset(kvm_regs, 0, sizeof kvm_regs); - r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs); - if (r) + r = -ENOMEM; + kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); + if (!kvm_regs) goto out; + r = kvm_arch_vcpu_ioctl_get_regs(vcpu, kvm_regs); + if (r) + goto out_free1; r = -EFAULT; - if (copy_to_user(argp, kvm_regs, sizeof kvm_regs)) - goto out; + if (copy_to_user(argp, kvm_regs, sizeof(struct kvm_regs))) + goto out_free1; r = 0; +out_free1: + kfree(kvm_regs); break; } case KVM_SET_REGS: { - struct kvm_regs kvm_regs; + struct kvm_regs *kvm_regs; - r = -EFAULT; - if (copy_from_user(kvm_regs, argp, sizeof kvm_regs)) + r = -ENOMEM; + kvm_regs = kzalloc(sizeof(struct kvm_regs), GFP_KERNEL); + if (!kvm_regs) goto out; - r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs); + r = -EFAULT; + if (copy_from_user(kvm_regs, argp, sizeof(struct kvm_regs))) + goto out_free2; + r = kvm_arch_vcpu_ioctl_set_regs(vcpu, kvm_regs); if (r) - goto out; + goto out_free2; r = 0; +out_free2: + kfree(kvm_regs); break; } case KVM_GET_SREGS: { -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 01/35] KVM: Use x86's segment descriptor struct instead of private definition
The x86 desc_struct unification allows us to remove segment_descriptor.h. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/segment_descriptor.h | 29 - arch/x86/kvm/vmx.c|3 +-- arch/x86/kvm/x86.c| 15 +++ 3 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 arch/x86/kvm/segment_descriptor.h diff --git a/arch/x86/kvm/segment_descriptor.h b/arch/x86/kvm/segment_descriptor.h deleted file mode 100644 index 56fc4c8..000 --- a/arch/x86/kvm/segment_descriptor.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __SEGMENT_DESCRIPTOR_H -#define __SEGMENT_DESCRIPTOR_H - -struct segment_descriptor { - u16 limit_low; - u16 base_low; - u8 base_mid; - u8 type : 4; - u8 system : 1; - u8 dpl : 2; - u8 present : 1; - u8 limit_high : 4; - u8 avl : 1; - u8 long_mode : 1; - u8 default_op : 1; - u8 granularity : 1; - u8 base_high; -} __attribute__((packed)); - -#ifdef CONFIG_X86_64 -/* LDT or TSS descriptor in the GDT. 16 bytes. */ -struct segment_descriptor_64 { - struct segment_descriptor s; - u32 base_higher; - u32 pad_zero; -}; - -#endif -#endif diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 2d5ccec..f46ad03 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -17,7 +17,6 @@ #include irq.h #include vmx.h -#include segment_descriptor.h #include mmu.h #include linux/kvm_host.h @@ -388,7 +387,7 @@ static void reload_tss(void) * VT restores TR but not its size. Useless. */ struct descriptor_table gdt; - struct segment_descriptor *descs; + struct desc_struct *descs; get_gdt(gdt); descs = (void *)gdt.base; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b7c32f6..a063f44 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -15,7 +15,6 @@ */ #include linux/kvm_host.h -#include segment_descriptor.h #include irq.h #include mmu.h @@ -29,6 +28,7 @@ #include asm/uaccess.h #include asm/msr.h +#include asm/desc.h #define MAX_IO_MSRS 256 #define CR0_RESERVED_BITS \ @@ -94,7 +94,7 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { unsigned long segment_base(u16 selector) { struct descriptor_table gdt; - struct segment_descriptor *d; + struct desc_struct *d; unsigned long table_base; unsigned long v; @@ -110,13 +110,12 @@ unsigned long segment_base(u16 selector) asm(sldt %0 : =g(ldt_selector)); table_base = segment_base(ldt_selector); } - d = (struct segment_descriptor *)(table_base + (selector ~7)); - v = d-base_low | ((unsigned long)d-base_mid 16) | - ((unsigned long)d-base_high 24); + d = (struct desc_struct *)(table_base + (selector ~7)); + v = d-base0 | ((unsigned long)d-base1 16) | + ((unsigned long)d-base2 24); #ifdef CONFIG_X86_64 - if (d-system == 0 (d-type == 2 || d-type == 9 || d-type == 11)) - v |= ((unsigned long) \ - ((struct segment_descriptor_64 *)d)-base_higher) 32; + if (d-s == 0 (d-type == 2 || d-type == 9 || d-type == 11)) + v |= ((unsigned long)((struct ldttss_desc64 *)d)-base3) 32; #endif return v; } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 14/35] KVM: Remove pointless desc_ptr #ifdef
The desc_struct changes left an unnecessary #ifdef; remove it. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |4 1 files changed, 0 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index b2c667f..51741f9 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -290,11 +290,7 @@ static void svm_hardware_enable(void *garbage) struct svm_cpu_data *svm_data; uint64_t efer; -#ifdef CONFIG_X86_64 - struct desc_ptr gdt_descr; -#else struct desc_ptr gdt_descr; -#endif struct desc_struct *gdt; int me = raw_smp_processor_id(); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 06/35] KVM: Implement dummy values for MSR_PERF_STATUS
From: Alexander Graf [EMAIL PROTECTED] Darwin relies on this and ceases to work without. Signed-off-by: Alexander Graf [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cf6261e..0dd038e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -426,6 +426,7 @@ static u32 msrs_to_save[] = { MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, #endif MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, + MSR_IA32_PERF_STATUS, }; static unsigned num_msrs_to_save; @@ -653,7 +654,6 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_MC0_MISC+12: case MSR_IA32_MC0_MISC+16: case MSR_IA32_UCODE_REV: - case MSR_IA32_PERF_STATUS: case MSR_IA32_EBL_CR_POWERON: /* MTRR registers */ case 0xfe: @@ -669,6 +669,12 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) case MSR_IA32_MISC_ENABLE: data = vcpu-arch.ia32_misc_enable_msr; break; + case MSR_IA32_PERF_STATUS: + /* TSC increment by tick */ + data = 1000ULL; + /* CPU multiplier */ + data |= (((uint64_t)4ULL) 40); + break; case MSR_EFER: data = vcpu-arch.shadow_efer; break; -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 04/35] KVM: SVM: make iopm_base static
From: Harvey Harrison [EMAIL PROTECTED] Fixes sparse warning as well. arch/x86/kvm/svm.c:69:15: warning: symbol 'iopm_base' was not declared. Should it be static? Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 7d73e93..ff6e5c8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -66,7 +66,7 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) return container_of(vcpu, struct vcpu_svm, vcpu); } -unsigned long iopm_base; +static unsigned long iopm_base; struct kvm_ldttss_desc { u16 limit0; -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 05/35] KVM: sparse fixes for kvm/x86.c
From: Harvey Harrison [EMAIL PROTECTED] In two case statements, use the ever popular 'i' instead of index: arch/x86/kvm/x86.c:1063:7: warning: symbol 'index' shadows an earlier one arch/x86/kvm/x86.c:1000:9: originally declared here arch/x86/kvm/x86.c:1079:7: warning: symbol 'index' shadows an earlier one arch/x86/kvm/x86.c:1000:9: originally declared here Make it static. arch/x86/kvm/x86.c:1945:24: warning: symbol 'emulate_ops' was not declared. Should it be static? Drop the return statements. arch/x86/kvm/x86.c:2878:2: warning: returning void-valued expression arch/x86/kvm/x86.c:2944:2: warning: returning void-valued expression Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c | 26 +- 1 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 15bba5d..cf6261e 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -1083,32 +1083,32 @@ static void do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, } /* function 4 and 0xb have additional index. */ case 4: { - int index, cache_type; + int i, cache_type; entry-flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; /* read more entries until cache_type is zero */ - for (index = 1; *nent maxnent; ++index) { - cache_type = entry[index - 1].eax 0x1f; + for (i = 1; *nent maxnent; ++i) { + cache_type = entry[i - 1].eax 0x1f; if (!cache_type) break; - do_cpuid_1_ent(entry[index], function, index); - entry[index].flags |= + do_cpuid_1_ent(entry[i], function, i); + entry[i].flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; ++*nent; } break; } case 0xb: { - int index, level_type; + int i, level_type; entry-flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; /* read more entries until level_type is zero */ - for (index = 1; *nent maxnent; ++index) { - level_type = entry[index - 1].ecx 0xff; + for (i = 1; *nent maxnent; ++i) { + level_type = entry[i - 1].ecx 0xff; if (!level_type) break; - do_cpuid_1_ent(entry[index], function, index); - entry[index].flags |= + do_cpuid_1_ent(entry[i], function, i); + entry[i].flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX; ++*nent; } @@ -1965,7 +1965,7 @@ void kvm_report_emulation_failure(struct kvm_vcpu *vcpu, const char *context) } EXPORT_SYMBOL_GPL(kvm_report_emulation_failure); -struct x86_emulate_ops emulate_ops = { +static struct x86_emulate_ops emulate_ops = { .read_std= emulator_read_std, .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, @@ -2899,7 +2899,7 @@ int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs) static void get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { - return kvm_x86_ops-get_segment(vcpu, var, seg); + kvm_x86_ops-get_segment(vcpu, var, seg); } void kvm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) @@ -2965,7 +2965,7 @@ int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu, static void set_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg) { - return kvm_x86_ops-set_segment(vcpu, var, seg); + kvm_x86_ops-set_segment(vcpu, var, seg); } int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 23/35] x86: KVM guest: hypercall batching
From: Marcelo Tosatti [EMAIL PROTECTED] Batch pte updates and tlb flushes in lazy MMU mode. [avi: - adjust to mmu_op - helper for getting para_state without debug warnings] Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kernel/kvm.c | 62 +++- 1 files changed, 60 insertions(+), 2 deletions(-) diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index 1bb6e97..d9121f9 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c @@ -26,6 +26,22 @@ #include linux/cpu.h #include linux/mm.h #include linux/highmem.h +#include linux/hardirq.h + +#define MMU_QUEUE_SIZE 1024 + +struct kvm_para_state { + u8 mmu_queue[MMU_QUEUE_SIZE]; + int mmu_queue_len; + enum paravirt_lazy_mode mode; +}; + +static DEFINE_PER_CPU(struct kvm_para_state, para_state); + +static struct kvm_para_state *kvm_para_state(void) +{ + return per_cpu(para_state, raw_smp_processor_id()); +} /* * No need for any IO delay on KVM @@ -48,6 +64,28 @@ static void kvm_mmu_op(void *buffer, unsigned len) } while (len); } +static void mmu_queue_flush(struct kvm_para_state *state) +{ + if (state-mmu_queue_len) { + kvm_mmu_op(state-mmu_queue, state-mmu_queue_len); + state-mmu_queue_len = 0; + } +} + +static void kvm_deferred_mmu_op(void *buffer, int len) +{ + struct kvm_para_state *state = kvm_para_state(); + + if (state-mode != PARAVIRT_LAZY_MMU) { + kvm_mmu_op(buffer, len); + return; + } + if (state-mmu_queue_len + len sizeof state-mmu_queue) + mmu_queue_flush(state); + memcpy(state-mmu_queue + state-mmu_queue_len, buffer, len); + state-mmu_queue_len += len; +} + static void kvm_mmu_write(void *dest, u64 val) { __u64 pte_phys; @@ -68,7 +106,7 @@ static void kvm_mmu_write(void *dest, u64 val) wpte.pte_val = val; wpte.pte_phys = pte_phys; - kvm_mmu_op(wpte, sizeof wpte); + kvm_deferred_mmu_op(wpte, sizeof wpte); } /* @@ -137,7 +175,7 @@ static void kvm_flush_tlb(void) .header.op = KVM_MMU_OP_FLUSH_TLB, }; - kvm_mmu_op(ftlb, sizeof ftlb); + kvm_deferred_mmu_op(ftlb, sizeof ftlb); } static void kvm_release_pt(u32 pfn) @@ -150,6 +188,23 @@ static void kvm_release_pt(u32 pfn) kvm_mmu_op(rpt, sizeof rpt); } +static void kvm_enter_lazy_mmu(void) +{ + struct kvm_para_state *state = kvm_para_state(); + + paravirt_enter_lazy_mmu(); + state-mode = paravirt_get_lazy_mode(); +} + +static void kvm_leave_lazy_mmu(void) +{ + struct kvm_para_state *state = kvm_para_state(); + + mmu_queue_flush(state); + paravirt_leave_lazy(paravirt_get_lazy_mode()); + state-mode = paravirt_get_lazy_mode(); +} + static void paravirt_ops_setup(void) { pv_info.name = KVM; @@ -177,6 +232,9 @@ static void paravirt_ops_setup(void) pv_mmu_ops.flush_tlb_user = kvm_flush_tlb; pv_mmu_ops.release_pt = kvm_release_pt; pv_mmu_ops.release_pd = kvm_release_pt; + + pv_mmu_ops.lazy_mode.enter = kvm_enter_lazy_mmu; + pv_mmu_ops.lazy_mode.leave = kvm_leave_lazy_mmu; } } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] Ubuntu Gutsy host / XP guest / -smp 2
David Abrahams wrote: With the title combination, the guest takes nearly 100% of my real CPU time and still only sees one CPU. Is this a known problem, and does it have a known solution? Can you send the output of 'kvm_stat -1'? Also, what does the guest think it is doing (in task manager, etc.)? What HAL do you see in device manager? -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] Fix endianness for virtio-blk config space
Anthony Liguori wrote: The virtio config space is little endian. Make sure that in virtio-blk we store the values in little endian format. Applied, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Andrea Arcangeli wrote: On Wed, Apr 02, 2008 at 07:32:35AM +0300, Avi Kivity wrote: It ought to work. gfn_to_hfn() (old gfn_to_page) will still need to take a refcount if possible. This reminds me, that mmu notifiers we could implement gfn_to_hfn only with follow_page and skip the refcounting on the struct page. I'm not suggesting that though, the refcount makes the code more robust IMHO, and notably it allows to run on kernels without mmu notifiers. Isn't it faster though? We don't need to pull in the cacheline containing the struct page anymore. We could hack something to make pre mmu notifier kernels work. I'm unsure if it's good to add struct pages for non-ram, I find it slightly confusing and not the right thing, it takes memory for stuff that can't happen (refcounting only makes sense if the page finally goes in the freelist when count reaches 0, and PG_dirty/referenced bits and the like don't make sense either for non-ram or reserved-ram). So I'm not sure the vmemmap trick is the best. I thought we'd meet with resistance to that idea :) though I'd like to point out that struct pages to exist for mmio on some machines (those with = 4GB). This will increase the potential for type errors, so maybe we need to make gfn_t and hfn_t distinct structures, and use accessors to get the actual values. That's also a possibility. If we go for this then hfn_t is probably a better name as it's less likely to collide with core kernel VM code. Otherwise perhaps pfn can be used instead of hfn, it's up to you ;). I guess we can move to pfn, they're unambiguous enough. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 2/2] Move in-kernel PIT device to separate file
Anthony Liguori wrote: This patch is mostly code motion to move the newly refactored in-kernel PIT device to a separate file. Applied both, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Andrea Arcangeli wrote: On Wed, Apr 02, 2008 at 12:50:50PM +0300, Avi Kivity wrote: Isn't it faster though? We don't need to pull in the cacheline containing the struct page anymore. Exactly, not only that, get_user_pages is likely a bit slower that we need for just kvm pte lookup. GRU uses follow_page directly because it runs in the tlb miss handler, for us instead the tlb miss handler doesn't invoke a page fault unless the spte is non present. How about this plan? 0. Merge mmu notifiers 1. gfn_to_page() - gfn_to_pfn() Still keeping the refcount. Change bad_page to kvm_bad_hfn. 2. Drop the refcounting from gfn_to_pfn() and from kvm_release_page_*() Still using get_user_pages() (and dropping the refcount immediately) Simultaneously, change hack_module.awk to add the refcount back. 3. Export follow_page() or something based on fast_gup(), and use it btw, if we change the method we use to read the Linux pte, I'd like to get the writable bit out of it. This was, when we create an spte for a gpte that is writable and dirty, we can set the spte writable iff the Linux pte is writable. This avoids breaking COW unnecessarily. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] KVM: add kvm_get_kvm and kvm_put_kvm functions
Izik Eidus wrote: From ebb9fe4765f1572314d2249e29a7ef4d0de07273 Mon Sep 17 00:00:00 2001 From: Izik Eidus [EMAIL PROTECTED] Date: Sun, 30 Mar 2008 15:48:35 +0300 Subject: [PATCH] KVM: add kvm_get_kvm and kvm_put_kvm functions, the main purpose of adding this functions is the abilaty to release the spinlock that protect the kvm list while still be able to do operations on a specific kvm in a safe way. Applied, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
[EMAIL PROTECTED] wrote: From: Ben-Ami Yassour [EMAIL PROTECTED] Enable a guest to access a device's memory mapped I/O regions directly. Userspace sends the mmio regions that the guest can access. On the first page fault for an access to an mmio address the host translates the gva to hpa, and updates the sptes. Can you explain why you're not using the regular memory slot mechanism? i.e. have userspace mmap(/dev/mem) and create a memslot containing that at the appropriate guest physical address? There are some issues with refcounting, but Andrea has some tricks to deal with that. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Anthony Liguori wrote: Regardless of whether we can use /dev/mem, I think we should introduce a new char device anyway. We only need to mmap() MMIO regions which are mapped by the PCI bus, presumably, the kernel should know about these mappings. The driver should only allow mappings that are valid for a particular PCI device such that it cannot be abused to map arbitrary regions of memory into a guest. Bonus points if it can validate that there isn't a valid Linux driver loaded for the given PCI device. Which is apparently entirely unnecessary as we already have /sys/bus/pci/.../region. It's just a matter of checking if a vma is VM_IO and then dealing with the subsequent reference counting issues as Avi points out. From idea to working implementation in 38 minutes. Congrats. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] KVM hangs with windows XP guest - help with debugging?
Jonathan Underwood wrote: Hi, I am trying to run Windows XP pro as a guest under kvm. The host system is Fedora 8. I have seen this behaviour with kvm-60 (as currently packaged for Fedora 8) and kvm-64 (using the rawhide package). Essentially, I install XP Pro successfuly. When I then try and run the SP2 exe in order to update it to SP2, KVM always freezes at the point where is says Running post install processes). The command line I am using is: /usr/bin/qemu-kvm -M pc -m 512 -smp 1 -monitor pty -localtime -no-acpi -boot c -hda /home/VM/WindowsXP.img -net nic,macaddr=00:16:3e:2a:1b:db,vlan=0 -net tap,fd=12,script=,vlan=0 -usb -usbdevice tablet -no-kvm-pit I have tried this both via virt-manager (i.e. connecting to the guest via vnc) and straight at the command line, and it happens for both. Host machine details: model name : Intel(R) Core(TM)2 CPU 6600 @ 2.40GHz kernel 2.6.24.3-50.fc8 (x86_64) When kvm hangs, there's no output produced on the console. What can I do to debug this further? Please run 'kvm_stat -1' (found in the tarball) while the guest is hanging and report the output. Also report whether the qemu process is consuming cpu or not. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Anthony Liguori wrote: I looked at Andrea's patches and I didn't see any special handling for non-RAM pages. Something Muli mentioned that kept them from doing /sys/devices/pci/.../region to begin with was the fact that IO pages do not have a struct page backing them so get_user_pages() will fail in gfn_to_page(). It's just something we discussed, not code. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Ben-Ami Yassour1 wrote: Can you explain why you're not using the regular memory slot mechanism? i.e. have userspace mmap(/dev/mem) and create a memslot containing that at the appropriate guest physical address? Our initial approach was to mmap /sys/bus/pci/devices/.../resource# and create a memory slot for it. However eventually we realized that for mmio we don't need hva mapped to the mmio region, we can map the gpa directly to hpa. As far as I understand, the memory slots mechanism is used to map gpa to hva. Then gfn_to_page uses get_user_pages to map hva to hpa. However, get_user_pages does not work for mmio, and in addition we know the hpa to begin with, so there is no real need to map an hva for the mmio region. In addition there is an assumption in the code that there is a page struct for the frame which is not the case for mmio. So it was easier to simply add a list of mmio gpa-hpa mapping. I guess we can use the memory slots array to holds the gpa to hpa mapping but it is not necessarily natural, and would probably require more hooks in the code to handle an mmio memory slot. BTW, note that for a guest that has multiple passthrough devices each with a set of mmio regions, it might become a long list, so there might be value to keep it separate from that respect as well. With regards to the potential security issue Anthony pointed out (ioctls taking hpa's) we can change the interface so that they will take (device, BAR) instead and the kernel will translate to hpa Not enough. How do you know if this calling process has permissions to access that pci device (I retract my previous pci passthrough is as rootish as you get remark). What do you think? Given that the shadow page table code has to be modified anyway (due to the struct page issue), is it worthwhile to experiment with mmap(...region) or is the current approach sufficient? As Anthony points out, the advantage to mmap() is that whatever security is needed can be applied at that level. Passing host physical addresses from userspace requires a whole new security model. The issue with gfn_to_page() is real. We can either try to work around it somehow, or we can try to back mmio regions with struct pages. Now that it looks like mem_map is becoming virtually mapped, the cost is minimal, but I expect this approach will meet some resistance. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Anthony Liguori wrote: You could get away with supporting reserved RAM another way though. If we refactored the MMU to use hfn_t instead of struct page, you would then need a mechanism to mmap() reserved ram into userspace (similar to ioremap I guess). In fact, you may be able to just lie and claim reserved ram is IO ram. We'd need it to return a (hfn_t, page_type_t) pair so the caller would know whether to use page refcounting or not. The caller might be able to ask Linux whether the page has a struct page or not, but it gets hairy. That's why I'm interested in the possibility of adding struct pages at runtime. vmemmap is needed for many other reasons (NUMA, memory hotplug, sparse SGI memory) so it's reasonable that it will be enabled on most distros. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/1] direct mmio for passthrough - kernel part
Anthony Liguori wrote: What about switching the KVM MMU code to use hfn_t instead of struct page? The initial conversion is pretty straight forward as the places where you actually need a struct page you can always get it from pfn_to_page() (like in kvm_release_page_dirty). We can then teach the MMU to deal with hfn_t's that don't have a corresponding page. IIUC, the implementation of something like kvm_release_page_dirty is a nop for pfn's that don't have a corresponding page. We just have to be able to detect a pfn_to_page() failure and then assume we're dealing with IO memory. It ought to work. gfn_to_hfn() (old gfn_to_page) will still need to take a refcount if possible. This will increase the potential for type errors, so maybe we need to make gfn_t and hfn_t distinct structures, and use accessors to get the actual values. -- Any sufficiently difficult bug is indistinguishable from a feature. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] KVM: MMU: Fix rmap_remove() race
Andrea Arcangeli wrote: I thought some more about this. BTW, for completeness: normally (with exception of vm_destroy) the put_page run by rmap_remove won't be the last one, but still the page can go in the freelist a moment after put_page runs (leading to the same problem). The VM is prevented to free the page while it's pinned, but the VM can do the final free on the page before rmap_remove returns. And w/o mmu notifiers there's no serialization that makes the core VM stop on the mmu_lock to wait the tlb flush to run, before the VM finally executes the last free of the page. mmu notifiers fixes this race for regular swapping as the core VM will block on the mmu_lock waiting the tlb flush (for this to work the tlb flush must always happen inside the mmu_lock unless the order is exactly spte = nonpresent; tlbflush; put_page). A VM_LOCKED on the vmas backing the anonymous memory will fix this for regolar swapping too (I did something like this in a patch at the end as a band-aid). But thinking more the moment we pretend to allow anybody to randomly __munmap__ any part of the guest physical address space like for ballooning while the guest runs (think unprivileged user owning /dev/kvm and running munmap at will), not even VM_LOCKED (ignored by munmap) and not even the mmu notifiers, can prevent the page to be queued in the kernel freelists immediately after rmap_remove returns, this is because rmap_remove may run in a different host-cpu in between unmap_vmas and invalidate_range_end. Running the ioctl before munmap won't help to prevent the race as the guest can still re-instantiate the sptes with page faults between the ioctl and munmap. However we've invalidate_range_begin. If we invalidate all sptes in invalidate_range_begin and we hold off the page faults in between _begin/_end, then we can fix this with the mmu notifiers. This can be done by taking mmu_lock in _begin and releasing it in _end, unless there's a lock dependency issue. So I think I can allow munmap safely (to unprivileged user too) by using _range_begin somehow. For this to work any relevant tlb flush must happen inside the _same_ mmu_lock critical section where spte=nonpresent and rmap_remove run too (thanks to the mmu_lock the ordering of those operations won't matter anymore, and no queue will be needed). I don't understand your conclusion: you prove that mlock() is not good enough, then post a patch to do it? I'll take another shot at fixing rmap_remove(), I don't like to cripple swapping for 2.6.25 (though it will only be really dependable in .26). -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [kvm-ppc-devel] virtio-net working on PowerPC KVM
Alexander Graf wrote: I am experiencing 7-8ms ping latencies (native 0.1ms) on x86_64 as well, when pinging the virtual machine. Maybe it's not related to PowerPC? Is it supposed to be that slow? If you have a really old host kernel, or a misconfigured one, it can happen. What's your host kernel? are you using hrtimers? -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [kvm-ppc-devel] virtio-net working on PowerPC KVM
Alexander Graf wrote: On Mar 31, 2008, at 9:43 AM, Avi Kivity wrote: Alexander Graf wrote: I am experiencing 7-8ms ping latencies (native 0.1ms) on x86_64 as well, when pinging the virtual machine. Maybe it's not related to PowerPC? Is it supposed to be that slow? If you have a really old host kernel, or a misconfigured one, it can happen. What's your host kernel? are you using hrtimers? This is a 2.6.22 SUSE kernel. As far as I can see CONFIG_HIGH_RES_TIMERS is not set. An alternative is -clock hpet or -clock rtc. Guess it's my fault then - nevertheless a warning when starting kvm would be nice. Yes, indeed. -- Do not meddle in the internals of kernels, for they are subtle and quick to panic. - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] kvm-64 hang
Farkas Levente wrote: hi, while kvm-62 works for us kmv-64 is hang at random position and even if it's start it's not able to login neither from net (can't connect) nor from console (through virt-manager's vnc i can give root username but after the password nothing happened). attached a screenshot of the boot hang of the 32bit system. there isn't any kind of log or error in any logfile. Please try: kvm-63 kvm-64 with the -no-kvm-pit command line option -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 07/40] KVM: x86 emulator: add group 7 decoding
This adds group decoding for opcode 0x0f 0x01 (group 7). Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c |9 +++-- 1 files changed, 7 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 7310368..ef6de16 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -70,7 +70,7 @@ #define GroupMask 0xff/* Group number stored in bits 0:7 */ enum { - Group1A, Group3_Byte, Group3, Group4, Group5, + Group1A, Group3_Byte, Group3, Group4, Group5, Group7, }; static u16 opcode_table[256] = { @@ -179,7 +179,7 @@ static u16 opcode_table[256] = { static u16 twobyte_table[256] = { /* 0x00 - 0x0F */ - 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, + 0, Group | GroupDual | Group7, 0, 0, 0, 0, ImplicitOps, 0, ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps | ModRM, 0, 0, /* 0x10 - 0x1F */ 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, 0, 0, 0, 0, 0, @@ -252,9 +252,14 @@ static u16 group_table[] = { [Group5*8] = DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0, SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, + [Group7*8] = + 0, 0, ModRM | SrcMem, ModRM | SrcMem, + SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, SrcMem | ModRM | ByteOp, }; static u16 group2_table[] = { + [Group7*8] = + SrcNone | ModRM, 0, 0, 0, SrcNone | ModRM | DstMem, 0, SrcMem | ModRM, 0, }; /* EFLAGS bit definitions. */ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 06/40] KVM: x86 emulator: Group decoding for groups 4 and 5
Add group decoding support for opcode 0xfe (group 4) and 0xff (group 5). Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 40 ++-- 1 files changed, 10 insertions(+), 30 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 52e65ae..7310368 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -70,7 +70,7 @@ #define GroupMask 0xff/* Group number stored in bits 0:7 */ enum { - Group1A, Group3_Byte, Group3, + Group1A, Group3_Byte, Group3, Group4, Group5, }; static u16 opcode_table[256] = { @@ -174,7 +174,7 @@ static u16 opcode_table[256] = { ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, /* 0xF8 - 0xFF */ ImplicitOps, 0, ImplicitOps, ImplicitOps, - 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM + 0, 0, Group | Group4, Group | Group5, }; static u16 twobyte_table[256] = { @@ -246,6 +246,12 @@ static u16 group_table[] = { DstMem | SrcImm | ModRM | SrcImm, 0, DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, 0, 0, 0, 0, + [Group4*8] = + ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, 0, 0, + [Group5*8] = + DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, 0, 0, + SrcMem | ModRM, 0, SrcMem | ModRM | Stack, 0, }; static u16 group2_table[] = { @@ -1097,7 +1103,6 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { struct decode_cache *c = ctxt-decode; - int rc; switch (c-modrm_reg) { case 0: /* inc */ @@ -1107,36 +1112,11 @@ static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt, emulate_1op(dec, c-dst, ctxt-eflags); break; case 4: /* jmp abs */ - if (c-b == 0xff) - c-eip = c-dst.val; - else { - DPRINTF(Cannot emulate %02x\n, c-b); - return X86EMUL_UNHANDLEABLE; - } + c-eip = c-src.val; break; case 6: /* push */ - - /* 64-bit mode: PUSH always pushes a 64-bit operand. */ - - if (ctxt-mode == X86EMUL_MODE_PROT64) { - c-dst.bytes = 8; - rc = ops-read_std((unsigned long)c-dst.ptr, - c-dst.val, 8, ctxt-vcpu); - if (rc != 0) - return rc; - } - register_address_increment(c-regs[VCPU_REGS_RSP], - -c-dst.bytes); - rc = ops-write_emulated(register_address(ctxt-ss_base, - c-regs[VCPU_REGS_RSP]), c-dst.val, - c-dst.bytes, ctxt-vcpu); - if (rc != 0) - return rc; - c-dst.type = OP_NONE; + emulate_push(ctxt); break; - default: - DPRINTF(Cannot emulate %02x\n, c-b); - return X86EMUL_UNHANDLEABLE; } return 0; } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 05/40] KVM: x86 emulator: Group decoding for group 3
This adds group decoding support for opcodes 0xf6, 0xf7 (group 3). Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 34 ++ 1 files changed, 10 insertions(+), 24 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index cf1ce7c..52e65ae 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -70,7 +70,7 @@ #define GroupMask 0xff/* Group number stored in bits 0:7 */ enum { - Group1A, + Group1A, Group3_Byte, Group3, }; static u16 opcode_table[256] = { @@ -171,8 +171,7 @@ static u16 opcode_table[256] = { 0, 0, 0, 0, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, - ImplicitOps, ImplicitOps, - ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM, + ImplicitOps, ImplicitOps, Group | Group3_Byte, Group | Group3, /* 0xF8 - 0xFF */ ImplicitOps, 0, ImplicitOps, ImplicitOps, 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM @@ -239,6 +238,14 @@ static u16 twobyte_table[256] = { static u16 group_table[] = { [Group1A*8] = DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, + [Group3_Byte*8] = + ByteOp | SrcImm | DstMem | ModRM, 0, + ByteOp | DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, + [Group3*8] = + DstMem | SrcImm | ModRM | SrcImm, 0, + DstMem | SrcNone | ModRM, ByteOp | DstMem | SrcNone | ModRM, + 0, 0, 0, 0, }; static u16 group2_table[] = { @@ -1070,26 +1077,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, switch (c-modrm_reg) { case 0 ... 1: /* test */ - /* -* Special case in Grp3: test has an immediate -* source operand. -*/ - c-src.type = OP_IMM; - c-src.ptr = (unsigned long *)c-eip; - c-src.bytes = (c-d ByteOp) ? 1 : c-op_bytes; - if (c-src.bytes == 8) - c-src.bytes = 4; - switch (c-src.bytes) { - case 1: - c-src.val = insn_fetch(s8, 1, c-eip); - break; - case 2: - c-src.val = insn_fetch(s16, 2, c-eip); - break; - case 4: - c-src.val = insn_fetch(s32, 4, c-eip); - break; - } emulate_2op_SrcV(test, c-src, c-dst, ctxt-eflags); break; case 2: /* not */ @@ -1103,7 +1090,6 @@ static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt, rc = X86EMUL_UNHANDLEABLE; break; } -done: return rc; } -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 13/40] KVM: VMX: Enable Virtual Processor Identification (VPID)
From: Sheng Yang [EMAIL PROTECTED] To allow TLB entries to be retained across VM entry and VM exit, the VMM can now identify distinct address spaces through a new virtual-processor ID (VPID) field of the VMCS. [avi: drop vpid_sync_all()] [avi: add cc to asm constraints] Signed-off-by: Sheng Yang [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/vmx.c | 80 +--- arch/x86/kvm/vmx.h |6 +++ include/asm-x86/kvm_host.h |1 + 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 8e14628..1157e8a 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -37,6 +37,9 @@ MODULE_LICENSE(GPL); static int bypass_guest_pf = 1; module_param(bypass_guest_pf, bool, 0); +static int enable_vpid = 1; +module_param(enable_vpid, bool, 0); + struct vmcs { u32 revision_id; u32 abort; @@ -71,6 +74,7 @@ struct vcpu_vmx { unsigned rip; } irq; } rmode; + int vpid; }; static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu) @@ -86,6 +90,9 @@ static DEFINE_PER_CPU(struct vmcs *, current_vmcs); static struct page *vmx_io_bitmap_a; static struct page *vmx_io_bitmap_b; +static DECLARE_BITMAP(vmx_vpid_bitmap, VMX_NR_VPIDS); +static DEFINE_SPINLOCK(vmx_vpid_lock); + static struct vmcs_config { int size; int order; @@ -204,6 +211,12 @@ static inline int vm_need_virtualize_apic_accesses(struct kvm *kvm) (irqchip_in_kernel(kvm))); } +static inline int cpu_has_vmx_vpid(void) +{ + return (vmcs_config.cpu_based_2nd_exec_ctrl + SECONDARY_EXEC_ENABLE_VPID); +} + static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr) { int i; @@ -214,6 +227,20 @@ static int __find_msr_index(struct vcpu_vmx *vmx, u32 msr) return -1; } +static inline void __invvpid(int ext, u16 vpid, gva_t gva) +{ +struct { + u64 vpid : 16; + u64 rsvd : 48; + u64 gva; +} operand = { vpid, 0, gva }; + +asm volatile (ASM_VMX_INVVPID + /* CF==1 or ZF==1 -- rc = -1 */ + ; ja 1f ; ud2 ; 1: + : : a(operand), c(ext) : cc, memory); +} + static struct kvm_msr_entry *find_msr_entry(struct vcpu_vmx *vmx, u32 msr) { int i; @@ -257,6 +284,14 @@ static void vcpu_clear(struct vcpu_vmx *vmx) vmx-launched = 0; } +static inline void vpid_sync_vcpu_all(struct vcpu_vmx *vmx) +{ + if (vmx-vpid == 0) + return; + + __invvpid(VMX_VPID_EXTENT_SINGLE_CONTEXT, vmx-vpid, 0); +} + static unsigned long vmcs_readl(unsigned long field) { unsigned long value; @@ -490,6 +525,7 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (vcpu-cpu != cpu) { vcpu_clear(vmx); kvm_migrate_apic_timer(vcpu); + vpid_sync_vcpu_all(vmx); } if (per_cpu(current_vmcs, cpu) != vmx-vmcs) { @@ -971,7 +1007,8 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) if (_cpu_based_exec_control CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { min = 0; opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | - SECONDARY_EXEC_WBINVD_EXITING; + SECONDARY_EXEC_WBINVD_EXITING | + SECONDARY_EXEC_ENABLE_VPID; if (adjust_vmx_controls(min, opt, MSR_IA32_VMX_PROCBASED_CTLS2, _cpu_based_2nd_exec_control) 0) return -EIO; @@ -1239,6 +1276,11 @@ static void exit_lmode(struct kvm_vcpu *vcpu) #endif +static void vmx_flush_tlb(struct kvm_vcpu *vcpu) +{ + vpid_sync_vcpu_all(to_vmx(vcpu)); +} + static void vmx_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) { vcpu-arch.cr4 = KVM_GUEST_CR4_MASK; @@ -1275,6 +1317,7 @@ static void vmx_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) static void vmx_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3) { + vmx_flush_tlb(vcpu); vmcs_writel(GUEST_CR3, cr3); if (vcpu-arch.cr0 X86_CR0_PE) vmx_fpu_deactivate(vcpu); @@ -1494,6 +1537,22 @@ out: return r; } +static void allocate_vpid(struct vcpu_vmx *vmx) +{ + int vpid; + + vmx-vpid = 0; + if (!enable_vpid || !cpu_has_vmx_vpid()) + return; + spin_lock(vmx_vpid_lock); + vpid = find_first_zero_bit(vmx_vpid_bitmap, VMX_NR_VPIDS); + if (vpid VMX_NR_VPIDS) { + vmx-vpid = vpid; + __set_bit(vpid, vmx_vpid_bitmap); + } + spin_unlock(vmx_vpid_lock); +} + /* * Sets up the vmcs for emulated real mode. */ @@ -1532,6 +1591,8 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) if (!vm_need_virtualize_apic_accesses(vmx-vcpu.kvm)) exec_control
[kvm-devel] [PATCH 09/40] KVM: Only x86 has pio
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- virt/kvm/kvm_main.c |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 04595fe..121e65c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -678,8 +678,10 @@ static int kvm_vcpu_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (vmf-pgoff == 0) page = virt_to_page(vcpu-run); +#ifdef CONFIG_X86 else if (vmf-pgoff == KVM_PIO_PAGE_OFFSET) page = virt_to_page(vcpu-arch.pio_data); +#endif else return VM_FAULT_SIGBUS; get_page(page); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 11/40] KVM: MMU: Decouple mmio from shadow page tables
Currently an mmio guest pte is encoded in the shadow pagetable as a not-present trapping pte, with the SHADOW_IO_MARK bit set. However nothing is ever done with this information, so maintaining it is a useless complication. This patch moves the check for mmio to before shadow ptes are instantiated, so the shadow code is never invoked for ptes that reference mmio. The code is simpler, and with future work, can be made to handle mmio concurrently. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 34 +++--- arch/x86/kvm/paging_tmpl.h | 17 - 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 6f8392d..6651dfa 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -101,8 +101,6 @@ static int dbg = 1; #define PT_FIRST_AVAIL_BITS_SHIFT 9 #define PT64_SECOND_AVAIL_BITS_SHIFT 52 -#define PT_SHADOW_IO_MARK (1ULL PT_FIRST_AVAIL_BITS_SHIFT) - #define VALID_PAGE(x) ((x) != INVALID_PAGE) #define PT64_LEVEL_BITS 9 @@ -200,7 +198,6 @@ static int is_present_pte(unsigned long pte) static int is_shadow_present_pte(u64 pte) { - pte = ~PT_SHADOW_IO_MARK; return pte != shadow_trap_nonpresent_pte pte != shadow_notrap_nonpresent_pte; } @@ -215,11 +212,6 @@ static int is_dirty_pte(unsigned long pte) return pte PT_DIRTY_MASK; } -static int is_io_pte(unsigned long pte) -{ - return pte PT_SHADOW_IO_MARK; -} - static int is_rmap_pte(u64 pte) { return is_shadow_present_pte(pte); @@ -538,7 +530,7 @@ static int is_empty_shadow_page(u64 *spt) u64 *end; for (pos = spt, end = pos + PAGE_SIZE / sizeof(u64); pos != end; pos++) - if ((*pos ~PT_SHADOW_IO_MARK) != shadow_trap_nonpresent_pte) { + if (*pos != shadow_trap_nonpresent_pte) { printk(KERN_ERR %s: %p %llx\n, __FUNCTION__, pos, *pos); return 0; @@ -926,13 +918,6 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte, if (pte_access ACC_USER_MASK) spte |= PT_USER_MASK; - if (is_error_page(page)) { - set_shadow_pte(shadow_pte, - shadow_trap_nonpresent_pte | PT_SHADOW_IO_MARK); - kvm_release_page_clean(page); - return; - } - spte |= page_to_phys(page); if ((pte_access ACC_WRITE_MASK) @@ -1002,7 +987,7 @@ static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, if (level == 1) { mmu_set_spte(vcpu, table[index], ACC_ALL, ACC_ALL, 0, write, 1, pt_write, gfn, page); - return pt_write || is_io_pte(table[index]); + return pt_write; } if (table[index] == shadow_trap_nonpresent_pte) { @@ -1039,6 +1024,13 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) page = gfn_to_page(vcpu-kvm, gfn); up_read(current-mm-mmap_sem); + /* mmio */ + if (is_error_page(page)) { + kvm_release_page_clean(page); + up_read(vcpu-kvm-slots_lock); + return 1; + } + spin_lock(vcpu-kvm-mmu_lock); kvm_mmu_free_some_pages(vcpu); r = __nonpaging_map(vcpu, v, write, gfn, page); @@ -1406,10 +1398,14 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, return; gfn = (gpte PT64_BASE_ADDR_MASK) PAGE_SHIFT; - down_read(current-mm-mmap_sem); + down_read(vcpu-kvm-slots_lock); page = gfn_to_page(vcpu-kvm, gfn); - up_read(current-mm-mmap_sem); + up_read(vcpu-kvm-slots_lock); + if (is_error_page(page)) { + kvm_release_page_clean(page); + return; + } vcpu-arch.update_pte.gfn = gfn; vcpu-arch.update_pte.page = page; } diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index c2fd2b9..4b55f46 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h @@ -399,6 +399,14 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, page = gfn_to_page(vcpu-kvm, walker.gfn); up_read(current-mm-mmap_sem); + /* mmio */ + if (is_error_page(page)) { + pgprintk(gfn %x is mmio\n, walker.gfn); + kvm_release_page_clean(page); + up_read(vcpu-kvm-slots_lock); + return 1; + } + spin_lock(vcpu-kvm-mmu_lock); kvm_mmu_free_some_pages(vcpu); shadow_pte = FNAME(fetch)(vcpu, addr, walker, user_fault, write_fault, @@ -409,15 +417,6 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, if (!write_pt) vcpu-arch.last_pt_write_count = 0; /* reset fork detector
[kvm-devel] [PATCH 04/40] KVM: x86 emulator: group decoding for group 1A
This adds group decode support for opcode 0x8f. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c |8 +++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 46ecf34..cf1ce7c 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -69,6 +69,10 @@ #define GroupDual (115) /* Alternate decoding of mod == 3 */ #define GroupMask 0xff/* Group number stored in bits 0:7 */ +enum { + Group1A, +}; + static u16 opcode_table[256] = { /* 0x00 - 0x07 */ ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, @@ -133,7 +137,7 @@ static u16 opcode_table[256] = { /* 0x88 - 0x8F */ ByteOp | DstMem | SrcReg | ModRM | Mov, DstMem | SrcReg | ModRM | Mov, ByteOp | DstReg | SrcMem | ModRM | Mov, DstReg | SrcMem | ModRM | Mov, - 0, ModRM | DstReg, 0, DstMem | SrcNone | ModRM | Mov | Stack, + 0, ModRM | DstReg, 0, Group | Group1A, /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ImplicitOps | Stack, ImplicitOps | Stack, 0, 0, @@ -233,6 +237,8 @@ static u16 twobyte_table[256] = { }; static u16 group_table[] = { + [Group1A*8] = + DstMem | SrcNone | ModRM | Mov | Stack, 0, 0, 0, 0, 0, 0, 0, }; static u16 group2_table[] = { -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 32/40] KVM: paravirtualized clocksource: host part
From: Glauber de Oliveira Costa [EMAIL PROTECTED] This is the host part of kvm clocksource implementation. As it does not include clockevents, it is a fairly simple implementation. We only have to register a per-vcpu area, and start writing to it periodically. The area is binary compatible with xen, as we use the same shadow_info structure. [marcelo: fix bad_page on MSR_KVM_SYSTEM_TIME] [avi: save full value of the msr, even if enable bit is clear] [avi: clear previous value of time_page] Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED] Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c | 113 +++- include/asm-x86/kvm_host.h |7 +++ include/asm-x86/kvm_para.h | 25 ++ include/linux/kvm.h|1 + 4 files changed, 145 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 0c910c7..256c0fc 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -19,6 +19,7 @@ #include irq.h #include mmu.h +#include linux/clocksource.h #include linux/kvm.h #include linux/fs.h #include linux/vmalloc.h @@ -424,7 +425,7 @@ static u32 msrs_to_save[] = { #ifdef CONFIG_X86_64 MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, #endif - MSR_IA32_TIME_STAMP_COUNTER, + MSR_IA32_TIME_STAMP_COUNTER, MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, }; static unsigned num_msrs_to_save; @@ -482,6 +483,70 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) return kvm_set_msr(vcpu, index, *data); } +static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) +{ + static int version; + struct kvm_wall_clock wc; + struct timespec wc_ts; + + if (!wall_clock) + return; + + version++; + + down_read(kvm-slots_lock); + kvm_write_guest(kvm, wall_clock, version, sizeof(version)); + + wc_ts = current_kernel_time(); + wc.wc_sec = wc_ts.tv_sec; + wc.wc_nsec = wc_ts.tv_nsec; + wc.wc_version = version; + + kvm_write_guest(kvm, wall_clock, wc, sizeof(wc)); + + version++; + kvm_write_guest(kvm, wall_clock, version, sizeof(version)); + up_read(kvm-slots_lock); +} + +static void kvm_write_guest_time(struct kvm_vcpu *v) +{ + struct timespec ts; + unsigned long flags; + struct kvm_vcpu_arch *vcpu = v-arch; + void *shared_kaddr; + + if ((!vcpu-time_page)) + return; + + /* Keep irq disabled to prevent changes to the clock */ + local_irq_save(flags); + kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER, + vcpu-hv_clock.tsc_timestamp); + ktime_get_ts(ts); + local_irq_restore(flags); + + /* With all the info we got, fill in the values */ + + vcpu-hv_clock.system_time = ts.tv_nsec + +(NSEC_PER_SEC * (u64)ts.tv_sec); + /* +* The interface expects us to write an even number signaling that the +* update is finished. Since the guest won't see the intermediate +* state, we just write 2 at the end +*/ + vcpu-hv_clock.version = 2; + + shared_kaddr = kmap_atomic(vcpu-time_page, KM_USER0); + + memcpy(shared_kaddr + vcpu-time_offset, vcpu-hv_clock, + sizeof(vcpu-hv_clock)); + + kunmap_atomic(shared_kaddr, KM_USER0); + + mark_page_dirty(v-kvm, vcpu-time PAGE_SHIFT); +} + int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) { @@ -511,6 +576,44 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) case MSR_IA32_MISC_ENABLE: vcpu-arch.ia32_misc_enable_msr = data; break; + case MSR_KVM_WALL_CLOCK: + vcpu-kvm-arch.wall_clock = data; + kvm_write_wall_clock(vcpu-kvm, data); + break; + case MSR_KVM_SYSTEM_TIME: { + if (vcpu-arch.time_page) { + kvm_release_page_dirty(vcpu-arch.time_page); + vcpu-arch.time_page = NULL; + } + + vcpu-arch.time = data; + + /* we verify if the enable bit is set... */ + if (!(data 1)) + break; + + /* ...but clean it before doing the actual write */ + vcpu-arch.time_offset = data ~(PAGE_MASK | 1); + + vcpu-arch.hv_clock.tsc_to_system_mul = + clocksource_khz2mult(tsc_khz, 22); + vcpu-arch.hv_clock.tsc_shift = 22; + + down_read(current-mm-mmap_sem); + down_read(vcpu-kvm-slots_lock); + vcpu-arch.time_page = + gfn_to_page(vcpu-kvm, data PAGE_SHIFT); + up_read(vcpu-kvm-slots_lock); + up_read(current-mm-mmap_sem
[kvm-devel] [PATCH 24/40] KVM: MMU: make the __nonpaging_map function generic
From: Joerg Roedel [EMAIL PROTECTED] The mapping function for the nonpaging case in the softmmu does basically the same as required for Nested Paging. Make this function generic so it can be used for both. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c |7 +++ 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 21cfa28..33cd7c9 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -979,10 +979,9 @@ static void nonpaging_new_cr3(struct kvm_vcpu *vcpu) { } -static int __nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, - gfn_t gfn, struct page *page) +static int __direct_map(struct kvm_vcpu *vcpu, gpa_t v, int write, + gfn_t gfn, struct page *page, int level) { - int level = PT32E_ROOT_LEVEL; hpa_t table_addr = vcpu-arch.mmu.root_hpa; int pt_write = 0; @@ -1042,7 +1041,7 @@ static int nonpaging_map(struct kvm_vcpu *vcpu, gva_t v, int write, gfn_t gfn) spin_lock(vcpu-kvm-mmu_lock); kvm_mmu_free_some_pages(vcpu); - r = __nonpaging_map(vcpu, v, write, gfn, page); + r = __direct_map(vcpu, v, write, gfn, page, PT32E_ROOT_LEVEL); spin_unlock(vcpu-kvm-mmu_lock); up_read(vcpu-kvm-slots_lock); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 34/40] KVM: x86 emulator: add ad_mask static inline
From: Harvey Harrison [EMAIL PROTECTED] Replaces open-coded mask calculation in macros. Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 11 --- 1 files changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 22900f7..f6f6544 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -480,10 +480,15 @@ static u16 group2_table[] = { (_type)_x; \ }) +static inline unsigned long ad_mask(struct decode_cache *c) +{ + return (1UL (c-ad_bytes 3)) - 1; +} + /* Access/update address held in a register, based on addressing mode. */ #define address_mask(reg) \ ((c-ad_bytes == sizeof(unsigned long)) ? \ - (reg) : ((reg) ((1UL (c-ad_bytes 3)) - 1))) + (reg) : ((reg) ad_mask(c))) #define register_address(base, reg) \ ((base) + address_mask(reg)) #define register_address_increment(reg, inc)\ @@ -494,9 +499,9 @@ static u16 group2_table[] = { (reg) += _inc; \ else\ (reg) = ((reg) \ -~((1UL (c-ad_bytes 3)) - 1)) | \ +~ad_mask(c)) | \ (((reg) + _inc)\ -((1UL (c-ad_bytes 3)) - 1));\ +ad_mask(c)); \ } while (0) #define JMP_REL(rel) \ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 35/40] KVM: x86 emulator: make register_address, address_mask static inlines
From: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 48 ++- 1 files changed, 29 insertions(+), 19 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index f6f6544..008db4d 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -486,11 +486,21 @@ static inline unsigned long ad_mask(struct decode_cache *c) } /* Access/update address held in a register, based on addressing mode. */ -#define address_mask(reg) \ - ((c-ad_bytes == sizeof(unsigned long)) ? \ - (reg) : ((reg) ad_mask(c))) -#define register_address(base, reg) \ - ((base) + address_mask(reg)) +static inline unsigned long +address_mask(struct decode_cache *c, unsigned long reg) +{ + if (c-ad_bytes == sizeof(unsigned long)) + return reg; + else + return reg ad_mask(c); +} + +static inline unsigned long +register_address(struct decode_cache *c, unsigned long base, unsigned long reg) +{ + return base + address_mask(c, reg); +} + #define register_address_increment(reg, inc)\ do {\ /* signed type ensures sign extension to long */\ @@ -1056,7 +1066,7 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt) c-dst.bytes = c-op_bytes; c-dst.val = c-src.val; register_address_increment(c-regs[VCPU_REGS_RSP], -c-op_bytes); - c-dst.ptr = (void *) register_address(ctxt-ss_base, + c-dst.ptr = (void *) register_address(c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]); } @@ -1066,7 +1076,7 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, struct decode_cache *c = ctxt-decode; int rc; - rc = ops-read_std(register_address(ctxt-ss_base, + rc = ops-read_std(register_address(c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]), c-dst.val, c-dst.bytes, ctxt-vcpu); if (rc != 0) @@ -1388,11 +1398,11 @@ special_insn: register_address_increment(c-regs[VCPU_REGS_RSP], -c-op_bytes); c-dst.ptr = (void *) register_address( - ctxt-ss_base, c-regs[VCPU_REGS_RSP]); + c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]); break; case 0x58 ... 0x5f: /* pop reg */ pop_instruction: - if ((rc = ops-read_std(register_address(ctxt-ss_base, + if ((rc = ops-read_std(register_address(c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]), c-dst.ptr, c-op_bytes, ctxt-vcpu)) != 0) goto done; @@ -1417,9 +1427,9 @@ special_insn: 1, (c-d ByteOp) ? 1 : c-op_bytes, c-rep_prefix ? - address_mask(c-regs[VCPU_REGS_RCX]) : 1, + address_mask(c, c-regs[VCPU_REGS_RCX]) : 1, (ctxt-eflags EFLG_DF), - register_address(ctxt-es_base, + register_address(c, ctxt-es_base, c-regs[VCPU_REGS_RDI]), c-rep_prefix, c-regs[VCPU_REGS_RDX]) == 0) { @@ -1433,9 +1443,9 @@ special_insn: 0, (c-d ByteOp) ? 1 : c-op_bytes, c-rep_prefix ? - address_mask(c-regs[VCPU_REGS_RCX]) : 1, + address_mask(c, c-regs[VCPU_REGS_RCX]) : 1, (ctxt-eflags EFLG_DF), - register_address(c-override_base ? + register_address(c, c-override_base ? *c-override_base : ctxt-ds_base, c-regs[VCPU_REGS_RSI]), @@ -1525,10 +1535,10 @@ special_insn: case 0xa4 ... 0xa5: /* movs */ c-dst.type = OP_MEM; c-dst.bytes = (c-d ByteOp) ? 1 : c-op_bytes; - c-dst.ptr = (unsigned long *)register_address( + c-dst.ptr = (unsigned long *)register_address(c, ctxt-es_base, c-regs[VCPU_REGS_RDI]); - if ((rc = ops
[kvm-devel] [PATCH 37/40] KVM: Add API to retrieve the number of supported vcpus per vm
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |3 +++ include/linux/kvm.h |1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 256c0fc..955d2ee 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -811,6 +811,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_VAPIC: r = !kvm_x86_ops-cpu_has_accelerated_tpr(); break; + case KVM_CAP_NR_VCPUS: + r = KVM_MAX_VCPUS; + break; default: r = 0; break; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index 94540b3..deb9c38 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -234,6 +234,7 @@ struct kvm_vapic_addr { #define KVM_CAP_VAPIC 6 #define KVM_CAP_EXT_CPUID 7 #define KVM_CAP_CLOCKSOURCE 8 +#define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ /* * ioctls for VM fds -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 36/40] KVM: x86 emulator: make register_address_increment and JMP_REL static inlines
From: Harvey Harrison [EMAIL PROTECTED] Change jmp_rel() to a function as well. Signed-off-by: Harvey Harrison [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 56 --- 1 files changed, 26 insertions(+), 30 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 008db4d..cacdcf5 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -501,23 +501,19 @@ register_address(struct decode_cache *c, unsigned long base, unsigned long reg) return base + address_mask(c, reg); } -#define register_address_increment(reg, inc)\ - do {\ - /* signed type ensures sign extension to long */\ - int _inc = (inc); \ - if (c-ad_bytes == sizeof(unsigned long)) \ - (reg) += _inc; \ - else\ - (reg) = ((reg) \ -~ad_mask(c)) | \ - (((reg) + _inc)\ -ad_mask(c)); \ - } while (0) +static inline void +register_address_increment(struct decode_cache *c, unsigned long *reg, int inc) +{ + if (c-ad_bytes == sizeof(unsigned long)) + *reg += inc; + else + *reg = (*reg ~ad_mask(c)) | ((*reg + inc) ad_mask(c)); +} -#define JMP_REL(rel) \ - do {\ - register_address_increment(c-eip, rel);\ - } while (0) +static inline void jmp_rel(struct decode_cache *c, int rel) +{ + register_address_increment(c, c-eip, rel); +} static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops, @@ -1065,7 +1061,7 @@ static inline void emulate_push(struct x86_emulate_ctxt *ctxt) c-dst.type = OP_MEM; c-dst.bytes = c-op_bytes; c-dst.val = c-src.val; - register_address_increment(c-regs[VCPU_REGS_RSP], -c-op_bytes); + register_address_increment(c, c-regs[VCPU_REGS_RSP], -c-op_bytes); c-dst.ptr = (void *) register_address(c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]); } @@ -1082,7 +1078,7 @@ static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt, if (rc != 0) return rc; - register_address_increment(c-regs[VCPU_REGS_RSP], c-dst.bytes); + register_address_increment(c, c-regs[VCPU_REGS_RSP], c-dst.bytes); return 0; } @@ -1395,7 +1391,7 @@ special_insn: c-dst.type = OP_MEM; c-dst.bytes = c-op_bytes; c-dst.val = c-src.val; - register_address_increment(c-regs[VCPU_REGS_RSP], + register_address_increment(c, c-regs[VCPU_REGS_RSP], -c-op_bytes); c-dst.ptr = (void *) register_address( c, ctxt-ss_base, c-regs[VCPU_REGS_RSP]); @@ -1407,7 +1403,7 @@ special_insn: c-op_bytes, ctxt-vcpu)) != 0) goto done; - register_address_increment(c-regs[VCPU_REGS_RSP], + register_address_increment(c, c-regs[VCPU_REGS_RSP], c-op_bytes); c-dst.type = OP_NONE; /* Disable writeback. */ break; @@ -1459,7 +1455,7 @@ special_insn: int rel = insn_fetch(s8, 1, c-eip); if (test_cc(c-b, ctxt-eflags)) - JMP_REL(rel); + jmp_rel(c, rel); break; } case 0x80 ... 0x83: /* Grp1 */ @@ -1545,10 +1541,10 @@ special_insn: c-dst.val, c-dst.bytes, ctxt-vcpu)) != 0) goto done; - register_address_increment(c-regs[VCPU_REGS_RSI], + register_address_increment(c, c-regs[VCPU_REGS_RSI], (ctxt-eflags EFLG_DF) ? -c-dst.bytes : c-dst.bytes); - register_address_increment(c-regs[VCPU_REGS_RDI], + register_address_increment(c, c-regs[VCPU_REGS_RDI], (ctxt-eflags EFLG_DF) ? -c-dst.bytes : c-dst.bytes); break; @@ -1580,10 +1576,10 @@ special_insn: emulate_2op_SrcV(cmp, c-src, c-dst, ctxt-eflags
[kvm-devel] [PATCH 38/40] KVM: Increase vcpu count to 16
With NPT support, scalability is much improved. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- include/linux/kvm_host.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index b90ca36..f4deb99 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -24,7 +24,7 @@ #include asm/kvm_host.h -#define KVM_MAX_VCPUS 4 +#define KVM_MAX_VCPUS 16 #define KVM_MEMORY_SLOTS 8 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 4 -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 25/40] KVM: export the load_pdptrs() function to modules
From: Joerg Roedel [EMAIL PROTECTED] The load_pdptrs() function is required in the SVM module for NPT support. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |1 + include/asm-x86/kvm_host.h |2 ++ 2 files changed, 3 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 38edb2f..0c910c7 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -213,6 +213,7 @@ out: return ret; } +EXPORT_SYMBOL_GPL(load_pdptrs); static bool pdptrs_changed(struct kvm_vcpu *vcpu) { diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 15fb2e8..da61255 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -410,6 +410,8 @@ void kvm_mmu_zap_all(struct kvm *kvm); unsigned int kvm_mmu_calculate_mmu_pages(struct kvm *kvm); void kvm_mmu_change_mmu_pages(struct kvm *kvm, unsigned int kvm_nr_mmu_pages); +int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); + enum emulation_result { EMULATE_DONE, /* no further processing */ EMULATE_DO_MMIO, /* kvm_run filled with mmio request */ -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 33/40] x86: KVM guest: paravirtualized clocksource
From: Glauber de Oliveira Costa [EMAIL PROTECTED] This is the guest part of kvm clock implementation It does not do tsc-only timing, as tsc can have deltas between cpus, and it did not seem worthy to me to keep adjusting them. We do use it, however, for fine-grained adjustment. Other than that, time comes from the host. [randy dunlap: add missing include] [randy dunlap: disallow on Voyager or Visual WS] Signed-off-by: Glauber de Oliveira Costa [EMAIL PROTECTED] Signed-off-by: Randy Dunlap [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/Kconfig | 11 +++ arch/x86/kernel/Makefile |1 + arch/x86/kernel/kvmclock.c | 160 arch/x86/kernel/setup_32.c |5 ++ arch/x86/kernel/setup_64.c |5 ++ 5 files changed, 182 insertions(+), 0 deletions(-) create mode 100644 arch/x86/kernel/kvmclock.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6c70fed..e59ea05 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -370,6 +370,17 @@ config VMI at the moment), by linking the kernel to a GPL-ed ROM module provided by the hypervisor. +config KVM_CLOCK + bool KVM paravirtualized clock + select PARAVIRT + depends on !(X86_VISWS || X86_VOYAGER) + help + Turning on this option will allow you to run a paravirtualized clock + when running over the KVM hypervisor. Instead of relying on a PIT + (or probably other) emulation by the underlying device model, the host + provides the guest with timing infrastructure such as time of day, and + system time + source arch/x86/lguest/Kconfig config PARAVIRT diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 4eb5ce8..a3379a3 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -77,6 +77,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o obj-$(CONFIG_DEBUG_NX_TEST)+= test_nx.o obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o +obj-$(CONFIG_KVM_CLOCK)+= kvmclock.o obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o ifdef CONFIG_INPUT_PCSPKR diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c new file mode 100644 index 000..b999f5e --- /dev/null +++ b/arch/x86/kernel/kvmclock.c @@ -0,0 +1,160 @@ +/* KVM paravirtual clock driver. A clocksource implementation +Copyright (C) 2008 Glauber de Oliveira Costa, Red Hat Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include linux/clocksource.h +#include linux/kvm_para.h +#include asm/arch_hooks.h +#include asm/msr.h +#include asm/apic.h +#include linux/percpu.h + +#define KVM_SCALE 22 + +static int kvmclock = 1; + +static int parse_no_kvmclock(char *arg) +{ + kvmclock = 0; + return 0; +} +early_param(no-kvmclock, parse_no_kvmclock); + +/* The hypervisor will put information about time periodically here */ +static DEFINE_PER_CPU_SHARED_ALIGNED(struct kvm_vcpu_time_info, hv_clock); +#define get_clock(cpu, field) per_cpu(hv_clock, cpu).field + +static inline u64 kvm_get_delta(u64 last_tsc) +{ + int cpu = smp_processor_id(); + u64 delta = native_read_tsc() - last_tsc; + return (delta * get_clock(cpu, tsc_to_system_mul)) KVM_SCALE; +} + +static struct kvm_wall_clock wall_clock; +static cycle_t kvm_clock_read(void); +/* + * The wallclock is the time of day when we booted. Since then, some time may + * have elapsed since the hypervisor wrote the data. So we try to account for + * that with system time + */ +unsigned long kvm_get_wallclock(void) +{ + u32 wc_sec, wc_nsec; + u64 delta; + struct timespec ts; + int version, nsec; + int low, high; + + low = (int)__pa(wall_clock); + high = ((u64)__pa(wall_clock) 32); + + delta = kvm_clock_read(); + + native_write_msr(MSR_KVM_WALL_CLOCK, low, high); + do { + version = wall_clock.wc_version; + rmb(); + wc_sec = wall_clock.wc_sec; + wc_nsec = wall_clock.wc_nsec; + rmb(); + } while ((wall_clock.wc_version != version) || (version 1)); + + delta = kvm_clock_read() - delta; + delta += wc_nsec; + nsec = do_div(delta, NSEC_PER_SEC
[kvm-devel] [PATCH 40/40] KVM: Increase the number of user memory slots per vm
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- include/linux/kvm_host.h |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f4deb99..eb88d32 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -25,7 +25,7 @@ #include asm/kvm_host.h #define KVM_MAX_VCPUS 16 -#define KVM_MEMORY_SLOTS 8 +#define KVM_MEMORY_SLOTS 32 /* memory slots that does not exposed to userspace */ #define KVM_PRIVATE_MEM_SLOTS 4 -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 39/40] KVM: Add API for determining the number of supported memory slots
Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c |3 +++ include/linux/kvm.h |1 + 2 files changed, 4 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 955d2ee..b7c32f6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -814,6 +814,9 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_NR_VCPUS: r = KVM_MAX_VCPUS; break; + case KVM_CAP_NR_MEMSLOTS: + r = KVM_MEMORY_SLOTS; + break; default: r = 0; break; diff --git a/include/linux/kvm.h b/include/linux/kvm.h index deb9c38..e92e703 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h @@ -235,6 +235,7 @@ struct kvm_vapic_addr { #define KVM_CAP_EXT_CPUID 7 #define KVM_CAP_CLOCKSOURCE 8 #define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */ +#define KVM_CAP_NR_MEMSLOTS 10 /* returns max memory slots per vm */ /* * ioctls for VM fds -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 31/40] KVM: SVM: enable LBR virtualization
From: Joerg Roedel [EMAIL PROTECTED] This patch implements the Last Branch Record Virtualization (LBRV) feature of the AMD Barcelona and Phenom processors into the kvm-amd module. It will only be enabled if the guest enables last branch recording in the DEBUG_CTL MSR. So there is no increased world switch overhead when the guest doesn't use these MSRs. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Markus Rechberger [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c | 39 +-- 1 files changed, 37 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 281a2ff..7d73e93 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -47,6 +47,8 @@ MODULE_LICENSE(GPL); #define SVM_FEATURE_LBRV (1 1) #define SVM_DEATURE_SVML (1 2) +#define DEBUGCTL_RESERVED_BITS (~(0x3fULL)) + /* enable NPT for AMD64 and X86 with PAE */ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) static bool npt_enabled = true; @@ -387,6 +389,28 @@ static void svm_vcpu_init_msrpm(u32 *msrpm) set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); } +static void svm_enable_lbrv(struct vcpu_svm *svm) +{ + u32 *msrpm = svm-msrpm; + + svm-vmcb-control.lbr_ctl = 1; + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 1, 1); +} + +static void svm_disable_lbrv(struct vcpu_svm *svm) +{ + u32 *msrpm = svm-msrpm; + + svm-vmcb-control.lbr_ctl = 0; + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHFROMIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTBRANCHTOIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTINTFROMIP, 0, 0); + set_msr_interception(msrpm, MSR_IA32_LASTINTTOIP, 0, 0); +} + static __init int svm_hardware_setup(void) { int cpu; @@ -1231,8 +1255,19 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) svm-vmcb-save.sysenter_esp = data; break; case MSR_IA32_DEBUGCTLMSR: - pr_unimpl(vcpu, %s: MSR_IA32_DEBUGCTLMSR 0x%llx, nop\n, - __FUNCTION__, data); + if (!svm_has(SVM_FEATURE_LBRV)) { + pr_unimpl(vcpu, %s: MSR_IA32_DEBUGCTL 0x%llx, nop\n, + __FUNCTION__, data); + break; + } + if (data DEBUGCTL_RESERVED_BITS) + return 1; + + svm-vmcb-save.dbgctl = data; + if (data (1ULL0)) + svm_enable_lbrv(svm); + else + svm_disable_lbrv(svm); break; case MSR_K7_EVNTSEL0: case MSR_K7_EVNTSEL1: -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 16/40] KVM: make EFER_RESERVED_BITS configurable for architecture code
From: Joerg Roedel [EMAIL PROTECTED] This patch give the SVM and VMX implementations the ability to add some bits the guest can set in its EFER register. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86.c | 11 +-- include/asm-x86/kvm_host.h |1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6b01552..ec9265b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -41,7 +41,7 @@ | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) -#define EFER_RESERVED_BITS 0xf2fe +static u64 __read_mostly efer_reserved_bits = 0xf2fe; #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 @@ -428,7 +428,7 @@ static u32 emulated_msrs[] = { static void set_efer(struct kvm_vcpu *vcpu, u64 efer) { - if (efer EFER_RESERVED_BITS) { + if (efer efer_reserved_bits) { printk(KERN_DEBUG set_efer: 0x%llx #GP, reserved bits\n, efer); kvm_inject_gp(vcpu, 0); @@ -452,6 +452,13 @@ static void set_efer(struct kvm_vcpu *vcpu, u64 efer) #endif +void kvm_enable_efer_bits(u64 mask) +{ + efer_reserved_bits = ~mask; +} +EXPORT_SYMBOL_GPL(kvm_enable_efer_bits); + + /* * Writes msr value into into the appropriate register. * Returns 0 on success, non-0 otherwise. diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 67ae307..92668fa 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -429,6 +429,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw, unsigned long realmode_get_cr(struct kvm_vcpu *vcpu, int cr); void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long value, unsigned long *rflags); +void kvm_enable_efer_bits(u64); int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data); int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 21/40] KVM: SVM: add detection of Nested Paging feature
From: Joerg Roedel [EMAIL PROTECTED] Let SVM detect if the Nested Paging feature is available on the hardware. Disable it to keep this patch series bisectable. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 5f527dc..c12a759 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -47,6 +47,8 @@ MODULE_LICENSE(GPL); #define SVM_FEATURE_LBRV (1 1) #define SVM_DEATURE_SVML (1 2) +static bool npt_enabled = false; + static void kvm_reput_irq(struct vcpu_svm *svm); static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) @@ -413,6 +415,12 @@ static __init int svm_hardware_setup(void) svm_features = cpuid_edx(SVM_CPUID_FUNC); + if (!svm_has(SVM_FEATURE_NPT)) + npt_enabled = false; + + if (npt_enabled) + printk(KERN_INFO kvm: Nested Paging enabled\n); + return 0; err_2: -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 17/40] KVM: align valid EFER bits with the features of the host system
From: Joerg Roedel [EMAIL PROTECTED] This patch aligns the bits the guest can set in the EFER register with the features in the host processor. Currently it lets EFER.NX disabled if the processor does not support it and enables EFER.LME and EFER.LMA only for KVM on 64 bit hosts. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |3 +++ arch/x86/kvm/vmx.c |4 arch/x86/kvm/x86.c | 10 +- 3 files changed, 16 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1a582f1..ff3bc74 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -403,6 +403,9 @@ static __init int svm_hardware_setup(void) set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1); set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1); + if (boot_cpu_has(X86_FEATURE_NX)) + kvm_enable_efer_bits(EFER_NX); + for_each_online_cpu(cpu) { r = svm_cpu_init(cpu); if (r) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 1157e8a..a509910 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1117,6 +1117,10 @@ static __init int hardware_setup(void) { if (setup_vmcs_config(vmcs_config) 0) return -EIO; + + if (boot_cpu_has(X86_FEATURE_NX)) + kvm_enable_efer_bits(EFER_NX); + return alloc_kvm_area(); } diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ec9265b..db16f23 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -41,7 +41,15 @@ | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE)) #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR) -static u64 __read_mostly efer_reserved_bits = 0xf2fe; +/* EFER defaults: + * - enable syscall per default because its emulated by KVM + * - enable LME and LMA per default on 64 bit KVM + */ +#ifdef CONFIG_X86_64 +static u64 __read_mostly efer_reserved_bits = 0xfafeULL; +#else +static u64 __read_mostly efer_reserved_bits = 0xfffeULL; +#endif #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 -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 22/40] KVM: SVM: add module parameter to disable Nested Paging
From: Joerg Roedel [EMAIL PROTECTED] To disable the use of the Nested Paging feature even if it is available in hardware this patch adds a module parameter. Nested Paging can be disabled by passing npt=0 to the kvm_amd module. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index c12a759..fb5d6c2 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -48,6 +48,9 @@ MODULE_LICENSE(GPL); #define SVM_DEATURE_SVML (1 2) static bool npt_enabled = false; +static int npt = 1; + +module_param(npt, int, S_IRUGO); static void kvm_reput_irq(struct vcpu_svm *svm); @@ -418,6 +421,11 @@ static __init int svm_hardware_setup(void) if (!svm_has(SVM_FEATURE_NPT)) npt_enabled = false; + if (npt_enabled !npt) { + printk(KERN_INFO kvm: Nested Paging disabled\n); + npt_enabled = false; + } + if (npt_enabled) printk(KERN_INFO kvm: Nested Paging enabled\n); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 23/40] KVM: export information about NPT to generic x86 code
From: Joerg Roedel [EMAIL PROTECTED] The generic x86 code has to know if the specific implementation uses Nested Paging. In the generic code Nested Paging is called Two Dimensional Paging (TDP) to avoid confusion with (future) TDP implementations of other vendors. This patch exports the availability of TDP to the generic x86 code. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 15 +++ arch/x86/kvm/svm.c |4 +++- include/asm-x86/kvm_host.h |2 ++ 3 files changed, 20 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 6651dfa..21cfa28 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -32,6 +32,15 @@ #include asm/cmpxchg.h #include asm/io.h +/* + * When setting this variable to true it enables Two-Dimensional-Paging + * where the hardware walks 2 page tables: + * 1. the guest-virtual to guest-physical + * 2. while doing 1. it walks guest-physical to host-physical + * If the hardware supports that we don't need to do shadow paging. + */ +static bool tdp_enabled = false; + #undef MMU_DEBUG #undef AUDIT @@ -1582,6 +1591,12 @@ out: } EXPORT_SYMBOL_GPL(kvm_mmu_page_fault); +void kvm_enable_tdp(void) +{ + tdp_enabled = true; +} +EXPORT_SYMBOL_GPL(kvm_enable_tdp); + static void free_mmu_pages(struct kvm_vcpu *vcpu) { struct kvm_mmu_page *sp; diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index fb5d6c2..9e29a13 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -426,8 +426,10 @@ static __init int svm_hardware_setup(void) npt_enabled = false; } - if (npt_enabled) + if (npt_enabled) { printk(KERN_INFO kvm: Nested Paging enabled\n); + kvm_enable_tdp(); + } return 0; diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 92668fa..15fb2e8 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -492,6 +492,8 @@ int kvm_fix_hypercall(struct kvm_vcpu *vcpu); int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code); +void kvm_enable_tdp(void); + int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3); int complete_pio(struct kvm_vcpu *vcpu); -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 27/40] KVM: SVM: add support for Nested Paging
From: Joerg Roedel [EMAIL PROTECTED] This patch contains the SVM architecture dependent changes for KVM to enable support for the Nested Paging feature of AMD Barcelona and Phenom processors. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c | 72 --- 1 files changed, 67 insertions(+), 5 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 9e29a13..8e9d4a5 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -47,7 +47,12 @@ MODULE_LICENSE(GPL); #define SVM_FEATURE_LBRV (1 1) #define SVM_DEATURE_SVML (1 2) +/* enable NPT for AMD64 and X86 with PAE */ +#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) +static bool npt_enabled = true; +#else static bool npt_enabled = false; +#endif static int npt = 1; module_param(npt, int, S_IRUGO); @@ -187,7 +192,7 @@ static inline void flush_guest_tlb(struct kvm_vcpu *vcpu) static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) { - if (!(efer EFER_LMA)) + if (!npt_enabled !(efer EFER_LMA)) efer = ~EFER_LME; to_svm(vcpu)-vmcb-save.efer = efer | MSR_EFER_SVME_MASK; @@ -573,6 +578,22 @@ static void init_vmcb(struct vmcb *vmcb) save-cr0 = 0x0010 | X86_CR0_PG | X86_CR0_WP; save-cr4 = X86_CR4_PAE; /* rdx = ?? */ + + if (npt_enabled) { + /* Setup VMCB for Nested Paging */ + control-nested_ctl = 1; + control-intercept_exceptions = ~(1 PF_VECTOR); + control-intercept_cr_read = ~(INTERCEPT_CR0_MASK| + INTERCEPT_CR3_MASK); + control-intercept_cr_write = ~(INTERCEPT_CR0_MASK| +INTERCEPT_CR3_MASK); + save-g_pat = 0x0007040600070406ULL; + /* enable caching because the QEMU Bios doesn't enable it */ + save-cr0 = X86_CR0_ET; + save-cr3 = 0; + save-cr4 = 0; + } + } static int svm_vcpu_reset(struct kvm_vcpu *vcpu) @@ -807,6 +828,9 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) } } #endif + if (npt_enabled) + goto set; + if ((vcpu-arch.cr0 X86_CR0_TS) !(cr0 X86_CR0_TS)) { svm-vmcb-control.intercept_exceptions = ~(1 NM_VECTOR); vcpu-fpu_active = 1; @@ -814,18 +838,26 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) vcpu-arch.cr0 = cr0; cr0 |= X86_CR0_PG | X86_CR0_WP; - cr0 = ~(X86_CR0_CD | X86_CR0_NW); if (!vcpu-fpu_active) { svm-vmcb-control.intercept_exceptions |= (1 NM_VECTOR); cr0 |= X86_CR0_TS; } +set: + /* +* re-enable caching here because the QEMU bios +* does not do it - this results in some delay at +* reboot +*/ + cr0 = ~(X86_CR0_CD | X86_CR0_NW); svm-vmcb-save.cr0 = cr0; } static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) { vcpu-arch.cr4 = cr4; - to_svm(vcpu)-vmcb-save.cr4 = cr4 | X86_CR4_PAE; + if (!npt_enabled) + cr4 |= X86_CR4_PAE; + to_svm(vcpu)-vmcb-save.cr4 = cr4; } static void svm_set_segment(struct kvm_vcpu *vcpu, @@ -1313,14 +1345,34 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm, [SVM_EXIT_WBINVD] = emulate_on_interception, [SVM_EXIT_MONITOR] = invalid_op_interception, [SVM_EXIT_MWAIT]= invalid_op_interception, + [SVM_EXIT_NPF] = pf_interception, }; - static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) { struct vcpu_svm *svm = to_svm(vcpu); u32 exit_code = svm-vmcb-control.exit_code; + if (npt_enabled) { + int mmu_reload = 0; + if ((vcpu-arch.cr0 ^ svm-vmcb-save.cr0) X86_CR0_PG) { + svm_set_cr0(vcpu, svm-vmcb-save.cr0); + mmu_reload = 1; + } + vcpu-arch.cr0 = svm-vmcb-save.cr0; + vcpu-arch.cr3 = svm-vmcb-save.cr3; + if (is_paging(vcpu) is_pae(vcpu) !is_long_mode(vcpu)) { + if (!load_pdptrs(vcpu, vcpu-arch.cr3)) { + kvm_inject_gp(vcpu, 0); + return 1; + } + } + if (mmu_reload) { + kvm_mmu_reset_context(vcpu); + kvm_mmu_load(vcpu); + } + } + kvm_reput_irq(svm); if (svm-vmcb-control.exit_code == SVM_EXIT_ERR) { @@ -1331,7 +1383,8 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) } if (is_external_interrupt(svm-vmcb
[kvm-devel] [PATCH 18/40] KVM: VMX: unifdef the EFER specific code
From: Joerg Roedel [EMAIL PROTECTED] To allow access to the EFER register in 32bit KVM the EFER specific code has to be exported to the x86 generic code. This patch does this in a backwards compatible manner. [avi: add check for EFER-less hosts] Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/vmx.c | 10 ++ 1 files changed, 2 insertions(+), 8 deletions(-) diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index a509910..76944f2 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -1335,14 +1335,14 @@ static void vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) vcpu-arch.cr4 = cr4; } -#ifdef CONFIG_X86_64 - static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) { struct vcpu_vmx *vmx = to_vmx(vcpu); struct kvm_msr_entry *msr = find_msr_entry(vmx, MSR_EFER); vcpu-arch.shadow_efer = efer; + if (!msr) + return; if (efer EFER_LMA) { vmcs_write32(VM_ENTRY_CONTROLS, vmcs_read32(VM_ENTRY_CONTROLS) | @@ -1359,8 +1359,6 @@ static void vmx_set_efer(struct kvm_vcpu *vcpu, u64 efer) setup_msrs(vmx); } -#endif - static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg) { struct kvm_vmx_segment_field *sf = kvm_vmx_segment_fields[seg]; @@ -1775,9 +1773,7 @@ static int vmx_vcpu_reset(struct kvm_vcpu *vcpu) vmx-vcpu.arch.cr0 = 0x6010; vmx_set_cr0(vmx-vcpu, vmx-vcpu.arch.cr0); /* enter rmode */ vmx_set_cr4(vmx-vcpu, 0); -#ifdef CONFIG_X86_64 vmx_set_efer(vmx-vcpu, 0); -#endif vmx_fpu_activate(vmx-vcpu); update_exception_bitmap(vmx-vcpu); @@ -2668,9 +2664,7 @@ static struct kvm_x86_ops vmx_x86_ops = { .set_cr0 = vmx_set_cr0, .set_cr3 = vmx_set_cr3, .set_cr4 = vmx_set_cr4, -#ifdef CONFIG_X86_64 .set_efer = vmx_set_efer, -#endif .get_idt = vmx_get_idt, .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt, -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 20/40] KVM: SVM: move feature detection to hardware setup code
From: Joerg Roedel [EMAIL PROTECTED] By moving the SVM feature detection from the each_cpu code to the hardware setup code it runs only once. As an additional advance the feature check is now available earlier in the module setup process. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/svm.c |4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index ff3bc74..5f527dc 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -302,7 +302,6 @@ static void svm_hardware_enable(void *garbage) svm_data-asid_generation = 1; svm_data-max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; svm_data-next_asid = svm_data-max_asid + 1; - svm_features = cpuid_edx(SVM_CPUID_FUNC); asm volatile (sgdt %0 : =m(gdt_descr)); gdt = (struct desc_struct *)gdt_descr.address; @@ -411,6 +410,9 @@ static __init int svm_hardware_setup(void) if (r) goto err_2; } + + svm_features = cpuid_edx(SVM_CPUID_FUNC); + return 0; err_2: -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 14/40] KVM: Use CONFIG_PREEMPT_NOTIFIERS around struct preempt_notifier
From: Hollis Blanchard [EMAIL PROTECTED] This allows kvm_host.h to be #included even when struct preempt_notifier is undefined. This is needed to build ppc asm-offsets.h. Signed-off-by: Hollis Blanchard [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- include/linux/kvm_host.h |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 928b0d5..b90ca36 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -67,7 +67,9 @@ void kvm_io_bus_register_dev(struct kvm_io_bus *bus, struct kvm_vcpu { struct kvm *kvm; +#ifdef CONFIG_PREEMPT_NOTIFIERS struct preempt_notifier preempt_notifier; +#endif int vcpu_id; struct mutex mutex; int cpu; -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 30/40] KVM: SVM: allocate the MSR permission map per VCPU
From: Joerg Roedel [EMAIL PROTECTED] This patch changes the kvm-amd module to allocate the SVM MSR permission map per VCPU instead of a global map for all VCPUs. With this we have more flexibility allowing specific guests to access virtualized MSRs. This is required for LBR virtualization. Signed-off-by: Joerg Roedel [EMAIL PROTECTED] Signed-off-by: Markus Rechberger [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/kvm_svm.h |2 + arch/x86/kvm/svm.c | 67 +++- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/arch/x86/kvm/kvm_svm.h b/arch/x86/kvm/kvm_svm.h index ecdfe97..65ef0fc 100644 --- a/arch/x86/kvm/kvm_svm.h +++ b/arch/x86/kvm/kvm_svm.h @@ -39,6 +39,8 @@ struct vcpu_svm { unsigned long host_db_regs[NUM_DB_REGS]; unsigned long host_dr6; unsigned long host_dr7; + + u32 *msrpm; }; #endif diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d934819..281a2ff 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -65,7 +65,6 @@ static inline struct vcpu_svm *to_svm(struct kvm_vcpu *vcpu) } unsigned long iopm_base; -unsigned long msrpm_base; struct kvm_ldttss_desc { u16 limit0; @@ -370,12 +369,29 @@ static void set_msr_interception(u32 *msrpm, unsigned msr, BUG(); } +static void svm_vcpu_init_msrpm(u32 *msrpm) +{ + memset(msrpm, 0xff, PAGE_SIZE * (1 MSRPM_ALLOC_ORDER)); + +#ifdef CONFIG_X86_64 + set_msr_interception(msrpm, MSR_GS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_FS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_KERNEL_GS_BASE, 1, 1); + set_msr_interception(msrpm, MSR_LSTAR, 1, 1); + set_msr_interception(msrpm, MSR_CSTAR, 1, 1); + set_msr_interception(msrpm, MSR_SYSCALL_MASK, 1, 1); +#endif + set_msr_interception(msrpm, MSR_K6_STAR, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_CS, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_ESP, 1, 1); + set_msr_interception(msrpm, MSR_IA32_SYSENTER_EIP, 1, 1); +} + static __init int svm_hardware_setup(void) { int cpu; struct page *iopm_pages; - struct page *msrpm_pages; - void *iopm_va, *msrpm_va; + void *iopm_va; int r; iopm_pages = alloc_pages(GFP_KERNEL, IOPM_ALLOC_ORDER); @@ -388,37 +404,13 @@ static __init int svm_hardware_setup(void) clear_bit(0x80, iopm_va); /* allow direct access to PC debug port */ iopm_base = page_to_pfn(iopm_pages) PAGE_SHIFT; - - msrpm_pages = alloc_pages(GFP_KERNEL, MSRPM_ALLOC_ORDER); - - r = -ENOMEM; - if (!msrpm_pages) - goto err_1; - - msrpm_va = page_address(msrpm_pages); - memset(msrpm_va, 0xff, PAGE_SIZE * (1 MSRPM_ALLOC_ORDER)); - msrpm_base = page_to_pfn(msrpm_pages) PAGE_SHIFT; - -#ifdef CONFIG_X86_64 - set_msr_interception(msrpm_va, MSR_GS_BASE, 1, 1); - set_msr_interception(msrpm_va, MSR_FS_BASE, 1, 1); - set_msr_interception(msrpm_va, MSR_KERNEL_GS_BASE, 1, 1); - set_msr_interception(msrpm_va, MSR_LSTAR, 1, 1); - set_msr_interception(msrpm_va, MSR_CSTAR, 1, 1); - set_msr_interception(msrpm_va, MSR_SYSCALL_MASK, 1, 1); -#endif - set_msr_interception(msrpm_va, MSR_K6_STAR, 1, 1); - set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_CS, 1, 1); - set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_ESP, 1, 1); - set_msr_interception(msrpm_va, MSR_IA32_SYSENTER_EIP, 1, 1); - if (boot_cpu_has(X86_FEATURE_NX)) kvm_enable_efer_bits(EFER_NX); for_each_online_cpu(cpu) { r = svm_cpu_init(cpu); if (r) - goto err_2; + goto err; } svm_features = cpuid_edx(SVM_CPUID_FUNC); @@ -438,10 +430,7 @@ static __init int svm_hardware_setup(void) return 0; -err_2: - __free_pages(msrpm_pages, MSRPM_ALLOC_ORDER); - msrpm_base = 0; -err_1: +err: __free_pages(iopm_pages, IOPM_ALLOC_ORDER); iopm_base = 0; return r; @@ -449,9 +438,8 @@ err_1: static __exit void svm_hardware_unsetup(void) { - __free_pages(pfn_to_page(msrpm_base PAGE_SHIFT), MSRPM_ALLOC_ORDER); __free_pages(pfn_to_page(iopm_base PAGE_SHIFT), IOPM_ALLOC_ORDER); - iopm_base = msrpm_base = 0; + iopm_base = 0; } static void init_seg(struct vmcb_seg *seg) @@ -536,7 +524,7 @@ static void init_vmcb(struct vcpu_svm *svm) (1ULL INTERCEPT_MWAIT); control-iopm_base_pa = iopm_base; - control-msrpm_base_pa = msrpm_base; + control-msrpm_base_pa = __pa(svm-msrpm); control-tsc_offset = 0; control-int_ctl = V_INTR_MASKING_MASK; @@ -615,6 +603,7 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) { struct vcpu_svm *svm; struct page *page
[kvm-devel] [PATCH 00/40] KVM updates for the 2.6.26 merge window (part I)
These are the first forty of about a hundred patches I have queued for 2.6.26. Note that a few will go through git-s390, maybe a couple through x86.git, and a few to 2.6.25-rc. The ia64 patches are not included as they are being reviewed, but I hope to have them merged in time for the 2.6.26 merge window. Happy reviewing! Diffstat for this batch: arch/x86/Kconfig | 11 ++ arch/x86/kernel/Makefile |1 + arch/x86/kernel/kvmclock.c | 160 arch/x86/kernel/setup_32.c |5 + arch/x86/kernel/setup_64.c |5 + arch/x86/kvm/kvm_svm.h |2 + arch/x86/kvm/mmu.c | 168 +++--- arch/x86/kvm/mmu.h |6 + arch/x86/kvm/paging_tmpl.h | 24 ++--- arch/x86/kvm/svm.c | 211 arch/x86/kvm/vmx.c | 100 +++--- arch/x86/kvm/vmx.h | 10 ++- arch/x86/kvm/x86.c | 147 +++-- arch/x86/kvm/x86_emulate.c | 252 --- include/asm-x86/kvm_host.h | 16 +++- include/asm-x86/kvm_para.h | 25 + include/linux/kvm.h|3 + include/linux/kvm_host.h |6 +- virt/kvm/kvm_main.c| 13 ++- 19 files changed, 919 insertions(+), 246 deletions(-) - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 02/40] KVM: MMU: Simplify hash table indexing
From: Dong, Eddie [EMAIL PROTECTED] Signed-off-by: Yaozu (Eddie) Dong [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/mmu.c | 10 +- include/asm-x86/kvm_host.h |3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 28f9a44..6f8392d 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -559,7 +559,7 @@ static void kvm_mmu_free_page(struct kvm *kvm, struct kvm_mmu_page *sp) static unsigned kvm_page_table_hashfn(gfn_t gfn) { - return gfn; + return gfn ((1 KVM_MMU_HASH_SHIFT) - 1); } static struct kvm_mmu_page *kvm_mmu_alloc_page(struct kvm_vcpu *vcpu, @@ -663,7 +663,7 @@ static struct kvm_mmu_page *kvm_mmu_lookup_page(struct kvm *kvm, gfn_t gfn) struct hlist_node *node; pgprintk(%s: looking for gfn %lx\n, __FUNCTION__, gfn); - index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES; + index = kvm_page_table_hashfn(gfn); bucket = kvm-arch.mmu_page_hash[index]; hlist_for_each_entry(sp, node, bucket, hash_link) if (sp-gfn == gfn !sp-role.metaphysical) { @@ -701,7 +701,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu, } pgprintk(%s: looking gfn %lx role %x\n, __FUNCTION__, gfn, role.word); - index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES; + index = kvm_page_table_hashfn(gfn); bucket = vcpu-kvm-arch.mmu_page_hash[index]; hlist_for_each_entry(sp, node, bucket, hash_link) if (sp-gfn == gfn sp-role.word == role.word) { @@ -840,7 +840,7 @@ static int kvm_mmu_unprotect_page(struct kvm *kvm, gfn_t gfn) pgprintk(%s: looking for gfn %lx\n, __FUNCTION__, gfn); r = 0; - index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES; + index = kvm_page_table_hashfn(gfn); bucket = kvm-arch.mmu_page_hash[index]; hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) if (sp-gfn == gfn !sp-role.metaphysical) { @@ -1450,7 +1450,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, vcpu-arch.last_pt_write_count = 1; vcpu-arch.last_pte_updated = NULL; } - index = kvm_page_table_hashfn(gfn) % KVM_NUM_MMU_PAGES; + index = kvm_page_table_hashfn(gfn); bucket = vcpu-kvm-arch.mmu_page_hash[index]; hlist_for_each_entry_safe(sp, node, n, bucket, hash_link) { if (sp-gfn != gfn || sp-role.metaphysical) diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 4702b04..d6db0de 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h @@ -57,7 +57,8 @@ #define KVM_PERMILLE_MMU_PAGES 20 #define KVM_MIN_ALLOC_MMU_PAGES 64 -#define KVM_NUM_MMU_PAGES 1024 +#define KVM_MMU_HASH_SHIFT 10 +#define KVM_NUM_MMU_PAGES (1 KVM_MMU_HASH_SHIFT) #define KVM_MIN_FREE_MMU_PAGES 5 #define KVM_REFILL_PAGES 25 #define KVM_MAX_CPUID_ENTRIES 40 -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 03/40] KVM: x86 emulator: add support for group decoding
Certain x86 instructions use bits 3:5 of the byte following the opcode as an opcode extension, with the decode sometimes depending on bits 6:7 as well. Add support for this in the main decoding table rather than an ad-hock adaptation per opcode. Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- arch/x86/kvm/x86_emulate.c | 33 +++-- 1 files changed, 27 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/x86_emulate.c b/arch/x86/kvm/x86_emulate.c index 7958600..46ecf34 100644 --- a/arch/x86/kvm/x86_emulate.c +++ b/arch/x86/kvm/x86_emulate.c @@ -65,6 +65,9 @@ #define MemAbs (19) /* Memory operand is absolute displacement */ #define String (110) /* String instruction (rep capable) */ #define Stack (111) /* Stack instruction (push/pop) */ +#define Group (114) /* Bits 3:5 of modrm byte extend opcode */ +#define GroupDual (115) /* Alternate decoding of mod == 3 */ +#define GroupMask 0xff/* Group number stored in bits 0:7 */ static u16 opcode_table[256] = { /* 0x00 - 0x07 */ @@ -229,6 +232,12 @@ static u16 twobyte_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static u16 group_table[] = { +}; + +static u16 group2_table[] = { +}; + /* EFLAGS bit definitions. */ #define EFLG_OF (111) #define EFLG_DF (110) @@ -763,7 +772,7 @@ x86_decode_insn(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) struct decode_cache *c = ctxt-decode; int rc = 0; int mode = ctxt-mode; - int def_op_bytes, def_ad_bytes; + int def_op_bytes, def_ad_bytes, group; /* Shadow copy of register state. Committed on successful emulation. */ @@ -864,12 +873,24 @@ done_prefixes: c-b = insn_fetch(u8, 1, c-eip); c-d = twobyte_table[c-b]; } + } - /* Unrecognised? */ - if (c-d == 0) { - DPRINTF(Cannot emulate %02x\n, c-b); - return -1; - } + if (c-d Group) { + group = c-d GroupMask; + c-modrm = insn_fetch(u8, 1, c-eip); + --c-eip; + + group = (group 3) + ((c-modrm 3) 7); + if ((c-d GroupDual) (c-modrm 6) == 3) + c-d = group2_table[group]; + else + c-d = group_table[group]; + } + + /* Unrecognised? */ + if (c-d == 0) { + DPRINTF(Cannot emulate %02x\n, c-b); + return -1; } if (mode == X86EMUL_MODE_PROT64 (c-d Stack)) -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
[kvm-devel] [PATCH 08/40] KVM: constify function pointer tables
From: Jan Engelhardt [EMAIL PROTECTED] Signed-off-by: Jan Engelhardt [EMAIL PROTECTED] Signed-off-by: Avi Kivity [EMAIL PROTECTED] --- virt/kvm/kvm_main.c |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index b2e1289..04595fe 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -705,7 +705,7 @@ static int kvm_vcpu_release(struct inode *inode, struct file *filp) return 0; } -static struct file_operations kvm_vcpu_fops = { +static const struct file_operations kvm_vcpu_fops = { .release= kvm_vcpu_release, .unlocked_ioctl = kvm_vcpu_ioctl, .compat_ioctl = kvm_vcpu_ioctl, @@ -1005,7 +1005,7 @@ static int kvm_vm_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static struct file_operations kvm_vm_fops = { +static const struct file_operations kvm_vm_fops = { .release= kvm_vm_release, .unlocked_ioctl = kvm_vm_ioctl, .compat_ioctl = kvm_vm_ioctl, -- 1.5.4.5 - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] hugetlbfs not working
Marcelo Tosatti wrote: QEMU/KVM: ftruncate() is not supported by hugetlbfs on older hosts Signed-off-by: Marcelo Tosatti [EMAIL PROTECTED] Applied, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [patch 0/2] separate thread for IO handling V2
Marcelo Tosatti wrote: - Fix reset, powerdown and shutdown. - Fix kvmctl. Unfortunately, this is still broken: - typing into a linux guest console, qemu locked up waiting for a signal - the regression tests still fail due to guest slowdown. I haven't isolated the cause yet (doesn't reproduce on my machines) -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] qemu: use ARRAY_SIZE macro as provided by osdep.h
Carlo Marcelo Arenas Belon wrote: included through qemu-kvm.h - cpu.h - cpu-defs.h for all architectures and resulting otherwise in : qemu/qemu-kvm-x86.c:23:1: warning: ARRAY_SIZE redefined In file included from ../cpu-defs.h:30, from qemu/target-i386/cpu.h:45, from ../qemu-common.h:62, from qemu/hw/hw.h:5, from qemu/qemu-kvm-x86.c:13: ../osdep.h:30:1: warning: this is the location of the previous definition Applied, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] qemu: remove conflicting dependency to linux/pci.h
Carlo Marcelo Arenas Belon wrote: remove dependency to the pci linux headers added since c10bf6159ff24501852c91a342c3077d5388b184 and that was generating the following conflict : qemu/hw/cirrus_vga.c:193:1: warning: PCI_COMMAND_SERR redefined In file included from /usr/include/linux/pci.h:21, from qemu/hw/pci.h:6, from qemu/hw/cirrus_vga.c:31: /usr/include/linux/pci_regs.h:40:1: warning: this is the location of the previous definition Applied, thanks. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 2/6] PCI DMA API
Anthony Liguori wrote: This patch introduces a PCI DMA API and some generic code to support other DMA APIs. Two types are introduced: PhysIOVector and IOVector. A DMA API maps a PhysIOVector, which is composed of target_phys_addr_t, into an IOVector, which is composed of void *. This enables zero-copy IO to be preformed without introducing assumptions of phys_ram_base. This API is at the PCI device level to enable support of per-device IOMMU remapping. + +typedef struct IOVector +{ +int num; +struct IOVectorElement { + void *base; + size_t len; +} sg[0]; +} IOVector; + Can we use 'struct iovec' for the element type (with accessors for setting base+len, and reading base or len, so we can substitute the Windows version for that platform)? That will allow using the vector without additional translation or casts. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] virtio-net working on PowerPC KVM
Hollis Blanchard wrote: I'm pleased to report that we now have working network support in the guest, via the virtio-net driver. In fact, we can use NFS for the guest's root filesystem. :) Boot log attached. Congrats! The bad news is that it's very slow, but the good news is that it's nice to be improving performance rather than debugging mysterious crashes... ;) With this milestone reached, in the near future I intend to start sending patches to Avi and linuxppc-dev for review, hopefully for inclusion in 2.6.26. However, I do want to see if we can improve the performance a little bit first... Low virtio net performance may be due to the virtio net host timer. What's your guest/host ping latency? Even if you have a good hrtimer implementation, I think you'll see 0.25ms latency, and that may be enough to slow down nfs. Unfortunately virtio is tuned for throughput at this time (it should be easy to disable the timer when we detect the queue is usually empty). -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] windows guest shows 15 virtual CPU´s i n device manager
Martin Maurer wrote: Hi all, I am running on kernel 2.6.24, KVM 63 – trying windows guests – working quite well. …but why tells the device manager that I have 15 CPU`s (QEMU Virtual CPU version 0.9.1)? The windows task manager is just showing one as expected. kvm provides 15 cpu slots, but only one of them has a cpu plugged in. Apparently device manager shows the slots, not the cpus. You can populate a cpu slot at runtime, but whether the the guest will use the cpu depends on the guest OS. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH] Use QEMU functions to access guest memory for virtio
Anthony Liguori wrote: I converted everything to use offsetof but left the accessors. You need a fair number of macros to handle the various data sizes and even then, I think it ends up looking nicer with the macros. See my patch series on qemu-devel and let me know if you agree/disagree. Accessors are fine, I just disliked the open-coded offsets. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [kvm-ia64-devel] [02/17][PATCH] Implement smp_call_function_mask for ia64
Zhang, Xiantao wrote: diff --git a/include/linux/smp.h b/include/linux/smp.h index 55232cc..b71820b 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -56,6 +56,9 @@ int smp_call_function(void(*func)(void *info), void *info, int retry, int wait); int smp_call_function_single(int cpuid, void (*func) (void *info), void *info, int retry, int wait); +int smp_call_function_mask(cpumask_t mask, +void (*func)(void *), void *info, +int wait); For all other archs, smp_call_function_mask() is declared in asm/smp.h so please define it there. A separate patch can move the declarations to linux/smp.h, since it makes sense to have just one declaration (and the uniprocessor version is declared there anyway). -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [Qemu-devel] [PATCH 2/6] PCI DMA API
Anthony Liguori wrote: This looks like it wouldn't scale to handle the Sparc systems. There we want to make more translation steps from DVMA addresses to physical in DMA controller and IOMMU and only in the final stage to void *. To handle this, probably there should be an opaque parameter and some way to register the translation function. Otherwise the API looks OK. I think having the PCI DMA API translate PhysIOVector = PhysIOVector would help. Then it becomes pretty easy to just call the DMA controller for additional translation from the IOMMU. Does that sound right? I don't quite understand what role the opaque parameter would serve. State for the dma controller. I think Blue is calling for chaining of dma mappings, no? Something similar is being proposed for the Linux dma api. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel
Re: [kvm-devel] [PATCH 1/3] [PATCH] passthrough
Glauber Costa wrote: add -passthrough usage string Signed-off-by: Glauber Costa [EMAIL PROTECTED] --- qemu/vl.c |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/qemu/vl.c b/qemu/vl.c index f5b2665..d36cfe3 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -8053,6 +8053,7 @@ #ifdef USE_KVM #ifndef NO_CPU_EMULATION -no-kvm disable KVM hardware virtualization\n #endif +-passthrough name/bus:dev.func-intr expose a pci device to the guest OS \n -no-kvm-irqchip disable KVM kernel mode PIC/IOAPIC/LAPIC\n #endif #ifdef TARGET_I386 Not this patch's fault, of course, but it would be better to name the option -pcidevice, to be consistent with -usbdevice, and to show only pci devices are allowed. -- error compiling committee.c: too many arguments to function - Check out the new SourceForge.net Marketplace. It's the best place to buy or sell services for just about anything Open Source. http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace ___ kvm-devel mailing list kvm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/kvm-devel