KVM: Decouple Intel VT implementation from base kvm
cover KVM: Decouple Intel VT implementation from base kvm
This patchset prepares kvm for multiple architecture implementations. The kvm.ko module is split into kvm.ko and kvm-intel.ko, and a function vector is used to dispatch arch specific operations to the arch module.
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 1/38 KVM: Create kvm-intel.ko module
This patch lays the foundation for arch-independent kvm: it creates the kvm-intel.ko module and prepares an arch function vector for the arch-specific implementation.
drivers/kvm/kvm.h +7 -0
@@ -235,11 +235,18 @@ struct kvm_stat {u32 irq_exits; }; +struct kvm_arch_ops { +}; +extern struct kvm_stat kvm_stat; +extern struct kvm_arch_ops *kvm_arch_ops; #define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt) #define vcpu_printf(vcpu, fmt...) kvm_printf(vcpu->kvm, fmt) +void kvm_init_arch (struct kvm_arch_ops *ops); +void kvm_exit_arch (void ); +void kvm_mmu_destroy (struct kvm_vcpu *vcpu);int kvm_mmu_init (struct kvm_vcpu *vcpu);
drivers/kvm/kvm_main.c +13 -0
@@ -41,6 +41,7 @@MODULE_AUTHOR ("Qumranet" );MODULE_LICENSE ("GPL" ); +struct kvm_arch_ops *kvm_arch_ops;struct kvm_stat kvm_stat; static struct kvm_stats_debugfs_item {
@@ -3611,6 +3612,15 @@ static void kvm_exit_debug(void)hpa_t bad_page_address; +void kvm_init_arch (struct kvm_arch_ops *ops) +{ + kvm_arch_ops = ops; +} + +void kvm_exit_arch (void ) +{ +} +static __init int kvm_init (void ) {static struct page *bad_page;
@@ -3670,3 +3680,6 @@ static __exit void kvm_exit(void) module_init(kvm_init) module_exit(kvm_exit) + +EXPORT_SYMBOL_GPL(kvm_init_arch); +EXPORT_SYMBOL_GPL(kvm_exit_arch);
drivers/kvm/vmx.c new file +39 -0
@@ -0,0 +1,39 @@ +/* +* Kernel-based Virtual Machine driver for Linux +* +* This module enables machines with Intel VT-x extensions to run virtual +* machines without emulation or binary translation. +* +* Copyright (C) 2006 Qumranet, Inc. +* +* Authors: +* Avi Kivity <avi-atKUWr5tajBWk0Htik3J/[email protected]> +* Yaniv Kamay <yaniv-atKUWr5tajBWk0Htik3J/[email protected]> +* +* This work is licensed under the terms of the GNU GPL, version 2. See +* the COPYING file in the top-level directory. +* +*/ + +#include "kvm.h" +#include <linux/module.h> + +MODULE_AUTHOR ("Qumranet" ); +MODULE_LICENSE ("GPL" ); + +static struct kvm_arch_ops vmx_arch_ops = { +}; + +static int __init vmx_init (void ) +{ +kvm_init_arch (&vmx_arch_ops); +return 0 ; +} + +static void __exit vmx_exit(void) +{ +kvm_exit_arch (); +} + +module_init (vmx_init) +module_exit (vmx_exit)
drivers/kvm/Kconfig +10 -2
@@ -6,8 +6,9 @@ config KVM depends on X86 && EXPERIMENTAL ---help--- Support hosting fully virtualized guest machines using hardware - virtualization extensions. You will need a fairly recent Intel - processor equipped with VT extensions. + virtualization extensions. You will need a fairly recent + processor equipped with virtualization extensions. You will also + need to select one or more of the processor modules below. This module provides access to the hardware capabilities through a character device node named /dev/kvm.
@@ -16,3 +17,10 @@ config KVM will be called kvm. If unsure, say N. + +config KVM_INTEL + tristate "KVM for Intel processors support" + depends on KVM + ---help--- + Provides support for KVM on Intel processors equipped with the VT + extensions.
drivers/kvm/Makefile +2 -0
@@ -4,3 +4,5 @@ kvm-objs := kvm_main.o mmu.o x86_emulate.o obj-$(CONFIG_KVM) += kvm.o +kvm-intel-objs = vmx.o +obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
drivers/kvm/kvm.h
Quoted 2 lines · Avi Kivity
drivers/kvm/kvm.h +0
-0
please move this from drivers/kvm/ to kernel/kvm/ [or even into a toplevel kvm/ directory] - KVM is not a "driver", KVM enhances the core Linux kernel with hypervisor functionality.
Guest paravirtualization drivers (once KVM implements them) can go into drivers/kvm/.
Ingo
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 9 lines · Ingo Molnar
drivers/kvm/kvm.h
Quoted 2 lines · Avi Kivity
drivers/kvm/kvm.h +0
-0please move this from
drivers/kvm/tokernel/kvm/[or even into a toplevel kvm/ directory] - KVM is not a "driver", KVM enhances the core Linux kernel with hypervisor functionality.
Actually it's exactly a driver. It's a character driver that exposes the virtualization features of modern x86 hardware. Pretty similar to things like the msr or mtrr driver that expose cpu features as character drivers aswell.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 6 lines · Christoph Hellwig
Quoted 3 lines
please move this from
drivers/kvm/tokernel/kvm/[or even into a toplevel kvm/ directory] - KVM is not a "driver", KVM enhances the core Linux kernel with hypervisor functionality.Actually it's exactly a driver. It's a character driver that exposes the virtualization features of modern x86 hardware. [...]
you are fundamentally wrong. In the end KVM is a fundamental and complex infrastructure that enables Linux to provide full hardware capabilities to another OS via the resources of this OS. This concept justifies a system call and a place in linux/kernel/. It's not fundamentally limited to x86 either. Full virtualization (and paravirtualization) makes sense on any platform. And there's no reason KVM be limited to full virtualization alone - both paravirtualization and accelerated guest drivers need a sane hypercall API.
Quoted 2 lines
[...] Pretty similar to things like the msr or mtrr driver that expose cpu features as character drivers aswell.
you can expose everything as character drivers and ioctls, but that doesnt make it the right solution. It might /start out/ as a driver, because that's an easy to hack model, but the moment something becomes important enough (and virtualization certainly is such a model) it demands a system call.
Just like inotify started out as an ioctl hack, but then was (rightfully) moved to the system-call space. [ Which btw. was on your request ;-) ]
Ingo
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 8 lines · On Thu, 30 Nov 2006 16:44:25 +0100 Ingo Molnar <[email protected]> wrote:
Quoted 2 lines
[...] Pretty similar to things like the msr or mtrr driver that expose cpu features as character drivers aswell.
you can expose everything as character drivers and ioctls, but that doesnt make it the right solution. It might /start out/ as a driver, because that's an easy to hack model, but the moment something becomes important enough (and virtualization certainly is such a model) it demands a system call.
Actually fourteen syscalls and counting, and some of those have `mode' arguments.
It's a fat, complex, presumably arch-specific, presumably frequently-changing API. So whatever we do will be unpleasant - that's unavoidable in this case, I suspect.
(hmm, the interface isn't versioned at present - should it be?)
Maybe, perhaps, one day it _should_ be a syscall API. But right now if we did that it would become a versioned syscall API with obsolete slots and various other warts.
I get the feeling we'd be best off if we were to revisit this in a year or so.
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 9 lines · Andrew Morton
It's a fat, complex, presumably arch-specific, presumably frequently-changing API. So whatever we do will be unpleasant - that's unavoidable in this case, I suspect.
(hmm, the interface isn't versioned at present - should it be?)
Maybe, perhaps, one day it _should_ be a syscall API. But right now if we did that it would become a versioned syscall API with obsolete slots and various other warts.
yeah, very much agreed. For example the paravirtualization/accelerator downcalls/upcalls in KVM dont exist yet, so there's little to standardize. Once we see it from lhype & KVM how these things look like we can design a sane kernel interface around it. But i'm against the notion that KVM is 'just' a device. It's not, and it /will/ grow into something fundamental.
Quoted 2 lines
I get the feeling we'd be best off if we were to revisit this in a year or so.
yeah. I'd suggest merging it as-is into v2.6.20. In a year we'll have some real APIs to think about.
Ingo
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 5 lines · Ingo Molnar
Quoted 2 lines
I get the feeling we'd be best off if we were to revisit this in a year or so.
yeah. I'd suggest merging it as-is into v2.6.20. In a year we'll have some real APIs to think about.
Agreed. And because of that I think keeping it in drivers/ for now makes a lot of sense - it's just a driver we can deprecate if/when things have evolved into a real infrastructure.
Re: [PATCH 1/38] KVM: Create kvm-intel.ko module
Quoted 10 lines · Christoph Hellwig
Quoted 5 lines · Ingo Molnar
Quoted 2 lines
I get the feeling we'd be best off if we were to revisit this in a year or so.
yeah. I'd suggest merging it as-is into v2.6.20. In a year we'll have some real APIs to think about.
Agreed. And because of that I think keeping it in
drivers/for now makes a lot of sense - it's just a driver we can deprecate if/when things have evolved into a real infrastructure.
yeah, with that understanding there's zero objections from me.
Ingo
PATCH 2/38 KVM: Make /dev/registration happen when the arch specific module is loaded
In reply to Avi KivityThis avoids exposing the driver capabilities before they are loaded.
drivers/kvm/kvm.h +1 -1
@@ -244,7 +244,7 @@ extern struct kvm_arch_ops *kvm_arch_ops #define kvm_printf(kvm, fmt ...) printk(KERN_DEBUG fmt) #define vcpu_printf(vcpu, fmt...) kvm_printf(vcpu->kvm, fmt) -void kvm_init_arch (struct kvm_arch_ops *ops); +int kvm_init_arch (struct kvm_arch_ops *ops,struct module *module);void kvm_exit_arch (void );void kvm_mmu_destroy (struct kvm_vcpu *vcpu);
drivers/kvm/kvm_main.c +14 -10
@@ -3558,7 +3558,6 @@ static int kvm_dev_mmap(struct file *fil }static struct file_operations kvm_chardev_ops = { - .owner =THIS_MODULE , .open = kvm_dev_open, .release = kvm_dev_release, .unlocked_ioctl = kvm_dev_ioctl,
@@ -3612,13 +3611,26 @@ static void kvm_exit_debug(void)hpa_t bad_page_address; -void kvm_init_arch (struct kvm_arch_ops *ops) +int kvm_init_arch (struct kvm_arch_ops *ops,struct module *module) { +int r; + kvm_arch_ops = ops; + kvm_chardev_ops.owner = module; + + r =misc_register (&kvm_dev); +if (r) { +printk (KERN_ERR "kvm: misc device register failed\n" ); + goto out_free; + } + +out_free: +return r; }void kvm_exit_arch (void ) { +misc_deregister (&kvm_dev); }static __init int kvm_init (void )
@@ -3644,13 +3656,6 @@ static __init int kvm_init(void)on_each_cpu (kvm_enable,0 ,0 ,1 );register_reboot_notifier (&kvm_reboot_notifier); - r =misc_register (&kvm_dev); -if (r) { -printk (KERN_ERR "kvm: misc device register failed\n" ); - goto out_free; - } - -if ((bad_page =alloc_page (GFP_KERNEL )) ==NULL ) { r = -ENOMEM ; goto out_free;
@@ -3671,7 +3676,6 @@ out: static __exit void kvm_exit(void) {kvm_exit_debug (); -misc_deregister (&kvm_dev);unregister_reboot_notifier (&kvm_reboot_notifier);on_each_cpu (kvm_disable,0 ,0 ,1 );free_kvm_area ();
drivers/kvm/vmx.c +1 -1
@@ -26,7 +26,7 @@ static struct kvm_arch_ops vmx_arch_opsstatic int __init vmx_init (void ) { -kvm_init_arch (&vmx_arch_ops); +kvm_init_arch (&vmx_arch_ops,THIS_MODULE );return 0 ; }
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Quoted 5 lines · Avi Kivity
This patchset prepares kvm for multiple architecture implementations. The kvm.ko module is split into kvm.ko and kvm-intel.ko, and a function vector is used to dispatch arch specific operations to the arch module.
It should be noted that the patchset is bisect friendly (and will even boot a guest for you at any point in the set).
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 3/38 KV: Make hardware detection an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -0
@@ -236,6 +236,8 @@ struct kvm_stat { };struct kvm_arch_ops { +int (*cpu_has_kvm_support)(void );/* __init */ +int (*disabled_by_bios)(void );/* __init */ };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +10 -23
@@ -527,12 +527,6 @@ static void free_vmcs(struct vmcs *vmcs)free_pages ((unsigned long )vmcs, vmcs_descriptor.order); } -static __init int cpu_has_kvm_support (void ) -{ -unsigned long ecx =cpuid_ecx (1 ); -return test_bit (5 , &ecx);/* CPUID.1:ECX.VMX[bit 5] -> VT */ -} - static __exit void free_kvm_area(void) {int cpu;
@@ -559,14 +553,6 @@ static __init int alloc_kvm_area(void)return 0 ; } -static __init int vmx_disabled_by_bios (void ) -{ -u64 msr; - -rdmsrl (MSR_IA32_FEATURE_CONTROL , msr); -return (msr &5 ) ==1 ;/* locked but not enabled */ -} -static __init void kvm_enable (void *garbage) {int cpu =raw_smp_processor_id ();
@@ -3616,6 +3602,16 @@ int kvm_init_arch(struct kvm_arch_ops *oint r; kvm_arch_ops = ops; + +if (!kvm_arch_ops->cpu_has_kvm_support ()) { +printk (KERN_ERR "kvm: no hardware support\n" ); +return -EOPNOTSUPP ; + } +if (kvm_arch_ops->disabled_by_bios ()) { +printk (KERN_ERR "kvm: disabled by bios\n" ); +return -EOPNOTSUPP ; + } + kvm_chardev_ops.owner = module; r =misc_register (&kvm_dev);
@@ -3638,15 +3634,6 @@ static __init int kvm_init(void)static struct page *bad_page;int r =0 ; -if (!cpu_has_kvm_support ()) { -printk (KERN_ERR "kvm: no hardware support\n" ); -return -EOPNOTSUPP ; - } -if (vmx_disabled_by_bios ()) { -printk (KERN_ERR "kvm: disabled by bios\n" ); -return -EOPNOTSUPP ; - } -kvm_init_debug ();setup_vmcs_descriptor ();
drivers/kvm/vmx.c +18 -0
@@ -18,10 +18,28 @@#include "kvm.h" #include <linux/module.h> +#define MSR_IA32_FEATURE_CONTROL 0x03a +MODULE_AUTHOR ("Qumranet" );MODULE_LICENSE ("GPL" ); +static __init int cpu_has_kvm_support (void ) +{ +unsigned long ecx =cpuid_ecx (1 ); +return test_bit (5 , &ecx);/* CPUID.1:ECX.VMX[bit 5] -> VT */ +} + +static __init int vmx_disabled_by_bios (void ) +{ +u64 msr; + +rdmsrl (MSR_IA32_FEATURE_CONTROL , msr); +return (msr &5 ) ==1 ;/* locked but not enabled */ +} +static struct kvm_arch_ops vmx_arch_ops = { + .cpu_has_kvm_support = cpu_has_kvm_support, + .disabled_by_bios = vmx_disabled_by_bios, };static int __init vmx_init (void )
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 4/38 KVM: Make the per-cpu enable/disable functions arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -0
@@ -238,6 +238,8 @@ struct kvm_stat {struct kvm_arch_ops {int (*cpu_has_kvm_support)(void );/* __init */ int (*disabled_by_bios)(void );/* __init */ +void (*hardware_enable)(void *dummy);/* __init */ +void (*hardware_disable)(void *dummy); };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +10 -28
@@ -135,7 +135,6 @@ static const u32 vmx_msr_index[] = {#define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL#define LMSW_GUEST_MASK 0x0eULL#define CR4_RESEVED_BITS (~((1ULL << 11) - 1)) -#define CR4_VMXE 0x2000#define CR8_RESEVED_BITS (~0x0fULL)#define EFER_RESERVED_BITS 0xfffffffffffff2fe
@@ -300,7 +299,8 @@ static void reload_tss(void)#endif } -static DEFINE_PER_CPU(struct vmcs *, vmxarea); +DEFINE_PER_CPU(struct vmcs *, vmxarea); +EXPORT_SYMBOL_GPL (per_cpu__vmxarea);/* temporary hack */ static DEFINE_PER_CPU(struct vmcs *, current_vmcs); static struct vmcs_descriptor {
@@ -553,26 +553,6 @@ static __init int alloc_kvm_area(void)return 0 ; } -static __init void kvm_enable (void *garbage) -{ -int cpu =raw_smp_processor_id (); -u64 phys_addr =__pa (per_cpu (vmxarea, cpu)); -u64 old; - -rdmsrl (MSR_IA32_FEATURE_CONTROL , old); -if ((old &5 ) ==0 ) -/* enable and lock */ -wrmsrl (MSR_IA32_FEATURE_CONTROL , old |5 ); -write_cr4 (read_cr4 () |CR4_VMXE );/* FIXME: not cpu hotplug safe */ - asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) - : "memory", "cc"); -} - -static void kvm_disable(void *garbage) -{ - asm volatile (ASM_VMX_VMXOFF : : : "cc"); -} -static int kvm_dev_open (struct inode *inode,struct file *filp) {struct kvm *kvm =kzalloc (sizeof (struct kvm ),GFP_KERNEL );
@@ -3565,8 +3545,8 @@ static int kvm_reboot(struct notifier_bl* Some (well, at least mine) BIOSes hang on reboot if * in vmx root mode. */ -printk (KERN_INFO "kvm: exiting vmx mode\n" ); -on_each_cpu (kvm_disable,0 ,0 ,1 ); +printk (KERN_INFO "kvm: exiting hardware virtualization\n" ); +on_each_cpu (kvm_arch_ops->hardware_disable,0 ,0 ,1 ); }return NOTIFY_OK ; }
@@ -3612,6 +3592,9 @@ int kvm_init_arch(struct kvm_arch_ops *oreturn -EOPNOTSUPP ; } +on_each_cpu (kvm_arch_ops->hardware_enable,0 ,0 ,1 ); +register_reboot_notifier (&kvm_reboot_notifier); + kvm_chardev_ops.owner = module; r =misc_register (&kvm_dev);
@@ -3627,6 +3610,9 @@ out_free:void kvm_exit_arch (void ) {misc_deregister (&kvm_dev); + +unregister_reboot_notifier (&kvm_reboot_notifier); +on_each_cpu (kvm_arch_ops->hardware_disable,0 ,0 ,1 ); }static __init int kvm_init (void )
@@ -3640,8 +3626,6 @@ static __init int kvm_init(void) r =alloc_kvm_area ();if (r) goto out; -on_each_cpu (kvm_enable,0 ,0 ,1 ); -register_reboot_notifier (&kvm_reboot_notifier);if ((bad_page =alloc_page (GFP_KERNEL )) ==NULL ) { r = -ENOMEM ;
@@ -3663,8 +3647,6 @@ out: static __exit void kvm_exit(void) {kvm_exit_debug (); -unregister_reboot_notifier (&kvm_reboot_notifier); -on_each_cpu (kvm_disable,0 ,0 ,1 );free_kvm_area ();__free_page (pfn_to_page (bad_page_address >>PAGE_SHIFT )); }
drivers/kvm/vmx.c +24 -0
@@ -23,6 +23,8 @@MODULE_AUTHOR ("Qumranet" );MODULE_LICENSE ("GPL" ); +DECLARE_PER_CPU(struct vmcs *, vmxarea); +static __init int cpu_has_kvm_support (void ) {unsigned long ecx =cpuid_ecx (1 );
@@ -37,9 +39,31 @@ static __init int vmx_disabled_by_bios(vreturn (msr &5 ) ==1 ;/* locked but not enabled */ } +static __init void hardware_enable (void *garbage) +{ +int cpu =raw_smp_processor_id (); +u64 phys_addr =__pa (per_cpu (vmxarea, cpu)); +u64 old; + +rdmsrl (MSR_IA32_FEATURE_CONTROL , old); +if ((old &5 ) ==0 ) +/* enable and lock */ +wrmsrl (MSR_IA32_FEATURE_CONTROL , old |5 ); +write_cr4 (read_cr4 () |CR4_VMXE );/* FIXME: not cpu hotplug safe */ + asm volatile (ASM_VMX_VMXON_RAX : : "a"(&phys_addr), "m"(phys_addr) + : "memory", "cc"); +} + +static void hardware_disable(void *garbage) +{ + asm volatile (ASM_VMX_VMXOFF : : : "cc"); +} +static struct kvm_arch_ops vmx_arch_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios, + .hardware_enable = hardware_enable, + .hardware_disable = hardware_disable, };static int __init vmx_init (void )
drivers/kvm/vmx.h +2 -0
@@ -284,4 +284,6 @@ enum vmcs_field {#define AR_RESERVD_MASK 0xfffe0f00 +#define CR4_VMXE 0x2000 +#endif
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 5/38 KVM: Make the hardware setup operations (non-percpu) arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -0
@@ -240,6 +240,8 @@ struct kvm_arch_ops {int (*disabled_by_bios)(void );/* __init */ void (*hardware_enable)(void *dummy);/* __init */ void (*hardware_disable)(void *dummy); +int (*hardware_setup)(void );/* __init */ +void (*hardware_unsetup)(void );/* __exit */ };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +17 -50
149 lines not on this page · raw message
drivers/kvm/vmx.c +59 -0
74 lines not on this page · raw message
drivers/kvm/vmx.h +2 -0
@@ -286,4 +286,6 @@ enum vmcs_field {#define CR4_VMXE 0x2000 +#define MSR_IA32_VMX_BASIC_MSR 0x480 +#endif
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 6/38 KVM: Make the guest debugger an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +3 -0
@@ -242,6 +242,9 @@ struct kvm_arch_ops {void (*hardware_disable)(void *dummy);int (*hardware_setup)(void );/* __init */ void (*hardware_unsetup)(void );/* __exit */ + +int (*set_guest_debug)(struct kvm_vcpu *vcpu, +struct kvm_debug_guest *dbg); };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +5 -38
70 lines not on this page · raw message
drivers/kvm/vmx.c +46 -0
58 lines not on this page · raw message
PATCH 7/38 KVM: Make msr accessors arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +4 -0
@@ -245,6 +245,8 @@ struct kvm_arch_ops {int (*set_guest_debug)(struct kvm_vcpu *vcpu,struct kvm_debug_guest *dbg); +int (*get_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 *pdata); +int (*set_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 data); };extern struct kvm_stat kvm_stat;
@@ -401,6 +403,8 @@ static inline struct kvm_mmu_page *page_#define ASM_VMX_VMXOFF ".byte 0x0f, 0x01, 0xc4"#define ASM_VMX_VMXON_RAX ".byte 0xf3, 0x0f, 0xc7, 0x30" +#define MSR_IA32_TIME_STAMP_COUNTER 0x010 +#ifdef __x86_64__/*
drivers/kvm/kvm_main.c +10 -117
195 lines not on this page · raw message
drivers/kvm/vmx.c +142 -0
154 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 8/38 KVM: Make the segment accessors arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +4 -0
@@ -247,6 +247,10 @@ struct kvm_arch_ops { struct kvm_debug_guest *dbg);int (*get_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 *pdata);int (*set_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 data); +void (*get_segment)(struct kvm_vcpu *vcpu, +struct kvm_segment *var,int seg); +void (*set_segment)(struct kvm_vcpu *vcpu, +struct kvm_segment *var,int seg); };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +25 -72
149 lines not on this page · raw message
drivers/kvm/vmx.c +58 -0
82 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 9/38 KVM: Cache guest cr4 in vcpu structure
In reply to Avi KivityThis eliminates needing to have an arch operation to get cr4.
drivers/kvm/kvm.h +5 -10
@@ -168,6 +168,7 @@ struct kvm_vcpu {unsigned long cr2;unsigned long cr3; +unsigned long cr4;unsigned long cr8;u64 shadow_efer;u64 apic_base;
@@ -335,20 +336,14 @@ static inline int is_long_mode(void)return vmcs_read32 (VM_ENTRY_CONTROLS ) &VM_ENTRY_CONTROLS_IA32E_MASK ; } -static inline unsigned long guest_cr4 (void ) +static inline int is_pae (struct kvm_vcpu *vcpu) { -return (vmcs_readl (CR4_READ_SHADOW ) &KVM_GUEST_CR4_MASK ) | - (vmcs_readl (GUEST_CR4 ) & ~KVM_GUEST_CR4_MASK ); +return vcpu->cr4 &CR4_PAE_MASK ; } -static inline int is_pae (void ) +static inline int is_pse (struct kvm_vcpu *vcpu) { -return guest_cr4 () &CR4_PAE_MASK ; -} - -static inline int is_pse (void ) -{ -return guest_cr4 () &CR4_PSE_MASK ; +return vcpu->cr4 &CR4_PSE_MASK ; }static inline unsigned long guest_cr0 (void )
drivers/kvm/kvm_main.c +9 -8
@@ -940,7 +940,7 @@ static void set_cr0(struct kvm_vcpu *vcp#ifdef __x86_64__if ((vcpu->shadow_efer &EFER_LME )) {u32 guest_cs_ar; -if (!is_pae ()) { +if (!is_pae (vcpu)) {printk (KERN_DEBUG "set_cr0: #GP, start paging " "in long mode while PAE is disabled\n" );inject_gp (vcpu);
@@ -956,7 +956,7 @@ static void set_cr0(struct kvm_vcpu *vcp } } else#endif -if (is_pae () && +if (is_pae (vcpu) &&pdptrs_have_reserved_bits_set (vcpu, vcpu->cr3)) {printk (KERN_DEBUG "set_cr0: #GP, pdptrs " "reserved bits\n" );
@@ -993,6 +993,7 @@ static void __set_cr4(struct kvm_vcpu *vvmcs_writel (CR4_READ_SHADOW , cr4);vmcs_writel (GUEST_CR4 , cr4 | (vcpu->rmode.active ?KVM_RMODE_VM_CR4_ALWAYS_ON :KVM_PMODE_VM_CR4_ALWAYS_ON )); + vcpu->cr4 = cr4; }static void set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4)
@@ -1010,7 +1011,7 @@ static void set_cr4(struct kvm_vcpu *vcpinject_gp (vcpu);return ; } - }else if (is_paging () && !is_pae () && (cr4 &CR4_PAE_MASK ) + }else if (is_paging () && !is_pae (vcpu) && (cr4 &CR4_PAE_MASK ) &&pdptrs_have_reserved_bits_set (vcpu, vcpu->cr3)) {printk (KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n" );inject_gp (vcpu);
@@ -1041,7 +1042,7 @@ static void set_cr3(struct kvm_vcpu *vcpinject_gp (vcpu);return ; } -if (is_paging () &&is_pae () && +if (is_paging () &&is_pae (vcpu) &&pdptrs_have_reserved_bits_set (vcpu, cr3)) {printk (KERN_DEBUG "set_cr3: #GP, pdptrs " "reserved bits\n" );
@@ -1902,7 +1903,7 @@ unsigned long realmode_get_cr(struct kvmcase 3 :return vcpu->cr3;case 4 : -return guest_cr4 (); +return vcpu->cr4;default :vcpu_printf (vcpu,"%s: unexpected cr %u\n" , __FUNCTION__, cr);return 0 ;
@@ -1924,7 +1925,7 @@ void realmode_set_cr(struct kvm_vcpu *vcset_cr3 (vcpu, val);break ;case 4 : -set_cr4 (vcpu,mk_cr_64 (guest_cr4 (), val)); +set_cr4 (vcpu,mk_cr_64 (vcpu->cr4, val));break ;default :vcpu_printf (vcpu,"%s: unexpected cr %u\n" , __FUNCTION__, cr);
@@ -2844,7 +2845,7 @@ static int kvm_dev_ioctl_get_sregs(struc sregs->cr0 =guest_cr0 (); sregs->cr2 = vcpu->cr2; sregs->cr3 = vcpu->cr3; - sregs->cr4 =guest_cr4 (); + sregs->cr4 = vcpu->cr4; sregs->cr8 = vcpu->cr8; sregs->efer = vcpu->shadow_efer; sregs->apic_base = vcpu->apic_base;
@@ -2912,7 +2913,7 @@ static int kvm_dev_ioctl_set_sregs(strucvmcs_writel (GUEST_CR0 , (sregs->cr0 & ~KVM_GUEST_CR0_MASK ) |KVM_VM_CR0_ALWAYS_ON ); - mmu_reset_needed |=guest_cr4 () != sregs->cr4; + mmu_reset_needed |= vcpu->cr4 != sregs->cr4;__set_cr4 (vcpu, sregs->cr4);if (mmu_reset_needed)
drivers/kvm/mmu.c +2 -2
@@ -564,7 +564,7 @@ static int paging64_init_context(struct {struct kvm_mmu *context = &vcpu->mmu; -ASSERT (is_pae ()); +ASSERT (is_pae (vcpu)); context->new_cr3 = paging_new_cr3; context->page_fault = paging64_page_fault; context->inval_page = paging_inval_page;
@@ -618,7 +618,7 @@ static int init_kvm_mmu(struct kvm_vcpureturn nonpaging_init_context (vcpu); else if (is_long_mode()) return paging64_init_context(vcpu); - else if (is_pae()) + else if (is_pae(vcpu)) return paging32E_init_context(vcpu); else return paging32_init_context(vcpu);
drivers/kvm/paging_tmpl.h +3 -3
@@ -70,7 +70,7 @@ static void FNAME(init_walker)(struct gu hpa =safe_gpa_to_hpa (vcpu, vcpu->cr3 &PT64_BASE_ADDR_MASK ); walker->table =kmap_atomic (pfn_to_page (hpa >>PAGE_SHIFT ),KM_USER0 ); -ASSERT ((!is_long_mode () &&is_pae ()) || +ASSERT ((!is_long_mode () &&is_pae (vcpu)) || (vcpu->cr3 & ~(PAGE_MASK |CR3_FLAGS_MASK )) ==0 ); walker->table = (pt_element_t *)( (unsigned long)walker->table |
@@ -133,7 +133,7 @@ static pt_element_t *FNAME(fetch_guest)( !is_present_pte (walker->table[index]) || (walker->level ==PT_DIRECTORY_LEVEL && (walker->table[index] &PT_PAGE_SIZE_MASK ) && - (PTTYPE == 64 || is_pse()))) + (PTTYPE == 64 || is_pse(vcpu)))) return &walker->table[index];if (walker->level !=3 ||is_long_mode ()) walker->inherited_ar &= walker->table[index];
@@ -369,7 +369,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvif (walker.level ==PT_DIRECTORY_LEVEL ) {ASSERT ((guest_pte &PT_PAGE_SIZE_MASK )); -ASSERT (PTTYPE ==64 ||is_pse ()); +ASSERT (PTTYPE ==64 ||is_pse (vcpu)); gpa = (guest_pte &PT_DIR_BASE_ADDR_MASK ) | (vaddr & (PT_LEVEL_MASK (PT_PAGE_TABLE_LEVEL ) | ~PAGE_MASK ));
drivers/kvm/kvm_vmx.h new file +20 -0
@@ -0,0 +1,20 @@ +#ifndef __KVM_VMX_H +#define __KVM_VMX_H + +static inline void vmcs_write16 (unsigned long field,u16 value) +{ +vmcs_writel (field, value); +} + +static inline void vmcs_write64 (unsigned long field,u64 value) +{ +#ifdef __x86_64__ +vmcs_writel (field, value); +#else +vmcs_writel (field, value); + asmvolatile ("" ); +vmcs_writel (field+1 , value >>32 ); +#endif +} + +#endif
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 10/38 KVM: Cache guest cr0 in vcpu structure
In reply to Avi KivityThis eliminates needing to have an arch operation to get cr0.
drivers/kvm/kvm.h +3 -9
@@ -41,7 +41,6 @@ | CR0_NW_MASK | CR0_CD_MASK)#define KVM_VM_CR0_ALWAYS_ON \ (CR0_PG_MASK | CR0_PE_MASK | CR0_WP_MASK | CR0_NE_MASK) -#define KVM_GUEST_CR4_MASK \ (CR4_PSE_MASK | CR4_PAE_MASK | CR4_PGE_MASK | CR4_VMXE_MASK | CR4_VME_MASK)#define KVM_PMODE_VM_CR4_ALWAYS_ON (CR4_VMXE_MASK | CR4_PAE_MASK)
@@ -166,6 +165,7 @@ struct kvm_vcpu {unsigned long regs[NR_VCPU_REGS ];/* for rsp: vcpu_load_rsp_rip() */ unsigned long rip;/* needs vcpu_load_rsp_rip() */ +unsigned long cr0;unsigned long cr2;unsigned long cr3;unsigned long cr4;
@@ -346,20 +346,14 @@ static inline int is_pse(struct kvm_vcpureturn vcpu->cr4 &CR4_PSE_MASK ; } -static inline unsigned long guest_cr0 (void ) -{ -return (vmcs_readl (CR0_READ_SHADOW ) &KVM_GUEST_CR0_MASK ) | - (vmcs_readl (GUEST_CR0 ) & ~KVM_GUEST_CR0_MASK ); -} -static inline unsigned guest_cpl (void ) {return vmcs_read16 (GUEST_CS_SELECTOR ) &SELECTOR_RPL_MASK ; } -static inline int is_paging (void ) +static inline int is_paging (struct kvm_vcpu *vcpu) { -return guest_cr0 () &CR0_PG_MASK ; +return vcpu->cr0 &CR0_PG_MASK ; }static inline int is_page_fault (u32 intr_info)
drivers/kvm/kvm_main.c +16 -12
@@ -875,9 +875,9 @@ static void __set_cr0(struct kvm_vcpu *v#ifdef __x86_64__if (vcpu->shadow_efer &EFER_LME ) { -if (!is_paging () && (cr0 &CR0_PG_MASK )) +if (!is_paging (vcpu) && (cr0 &CR0_PG_MASK ))enter_lmode (vcpu); -if (is_paging () && !(cr0 &CR0_PG_MASK )) +if (is_paging (vcpu) && !(cr0 &CR0_PG_MASK ))exit_lmode (vcpu); }#endif
@@ -885,6 +885,7 @@ static void __set_cr0(struct kvm_vcpu *vvmcs_writel (CR0_READ_SHADOW , cr0);vmcs_writel (GUEST_CR0 , (cr0 & ~KVM_GUEST_CR0_MASK ) |KVM_VM_CR0_ALWAYS_ON ); + vcpu->cr0 = cr0; } static int pdptrs_have_reserved_bits_set(struct kvm_vcpu *vcpu,
@@ -918,7 +919,7 @@ static void set_cr0(struct kvm_vcpu *vcp {if (cr0 &CR0_RESEVED_BITS ) {printk (KERN_DEBUG "set_cr0: 0x%lx #GP, reserved bits 0x%lx\n" , - cr0,guest_cr0 ()); + cr0, vcpu->cr0);inject_gp (vcpu);return ; }
@@ -936,7 +937,7 @@ static void set_cr0(struct kvm_vcpu *vcpreturn ; } -if (!is_paging () && (cr0 &CR0_PG_MASK )) { +if (!is_paging (vcpu) && (cr0 &CR0_PG_MASK )) {#ifdef __x86_64__if ((vcpu->shadow_efer &EFER_LME )) {u32 guest_cs_ar;
@@ -975,7 +976,7 @@ static void set_cr0(struct kvm_vcpu *vcpstatic void lmsw (struct kvm_vcpu *vcpu,unsigned long msw) { -unsigned long cr0 =guest_cr0 (); +unsigned long cr0 = vcpu->cr0;if ((msw &CR0_PE_MASK ) && !(cr0 &CR0_PE_MASK )) {enter_pmode (vcpu);
@@ -986,6 +987,7 @@ static void lmsw(struct kvm_vcpu *vcpu,vmcs_writel (GUEST_CR0 , (vmcs_readl (GUEST_CR0 ) & ~LMSW_GUEST_MASK ) | (msw &LMSW_GUEST_MASK )); + vcpu->cr0 = (vcpu->cr0 & ~0xfffful ) | msw; }static void __set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4)
@@ -1011,7 +1013,7 @@ static void set_cr4(struct kvm_vcpu *vcpinject_gp (vcpu);return ; } - }else if (is_paging () && !is_pae (vcpu) && (cr4 &CR4_PAE_MASK ) + }else if (is_paging (vcpu) && !is_pae (vcpu) && (cr4 &CR4_PAE_MASK ) &&pdptrs_have_reserved_bits_set (vcpu, vcpu->cr3)) {printk (KERN_DEBUG "set_cr4: #GP, pdptrs reserved bits\n" );inject_gp (vcpu);
@@ -1042,7 +1044,7 @@ static void set_cr3(struct kvm_vcpu *vcpinject_gp (vcpu);return ; } -if (is_paging () &&is_pae (vcpu) && +if (is_paging (vcpu) &&is_pae (vcpu) &&pdptrs_have_reserved_bits_set (vcpu, cr3)) {printk (KERN_DEBUG "set_cr3: #GP, pdptrs " "reserved bits\n" );
@@ -1897,7 +1899,7 @@ unsigned long realmode_get_cr(struct kvm {switch (cr) {case 0 : -return guest_cr0 (); +return vcpu->cr0;case 2 :return vcpu->cr2;case 3 :
@@ -1915,7 +1917,7 @@ void realmode_set_cr(struct kvm_vcpu *vc {switch (cr) {case 0 : -set_cr0 (vcpu,mk_cr_64 (guest_cr0 (), val)); +set_cr0 (vcpu,mk_cr_64 (vcpu->cr0, val)); *rflags =vmcs_readl (GUEST_RFLAGS );break ;case 2 :
@@ -2264,7 +2266,8 @@ void set_efer(struct kvm_vcpu *vcpu, u64return ; } -if (is_paging () && (vcpu->shadow_efer &EFER_LME ) != (efer &EFER_LME )) { +if (is_paging (vcpu) + && (vcpu->shadow_efer &EFER_LME ) != (efer &EFER_LME )) {printk (KERN_DEBUG "set_efer: #GP, change LME while paging\n" );inject_gp (vcpu);return ;
@@ -2842,7 +2845,7 @@ static int kvm_dev_ioctl_get_sregs(strucget_dtable (gdt,GDTR );#undef get_dtable - sregs->cr0 =guest_cr0 (); + sregs->cr0 = vcpu->cr0; sregs->cr2 = vcpu->cr2; sregs->cr3 = vcpu->cr3; sregs->cr4 = vcpu->cr4;
@@ -2906,12 +2909,13 @@ static int kvm_dev_ioctl_set_sregs(struc#endif vcpu->apic_base = sregs->apic_base; - mmu_reset_needed |=guest_cr0 () != sregs->cr0; + mmu_reset_needed |= vcpu->cr0 != sregs->cr0; vcpu->rmode.active = ((sregs->cr0 &CR0_PE_MASK ) ==0 );update_exception_bitmap (vcpu);vmcs_writel (CR0_READ_SHADOW , sregs->cr0);vmcs_writel (GUEST_CR0 , (sregs->cr0 & ~KVM_GUEST_CR0_MASK ) |KVM_VM_CR0_ALWAYS_ON ); + vcpu->cr0 = sregs->cr0; mmu_reset_needed |= vcpu->cr4 != sregs->cr4;__set_cr4 (vcpu, sregs->cr4);
drivers/kvm/mmu.c +4 -4
@@ -138,9 +138,9 @@#define PT_DIRECTORY_LEVEL 2#define PT_PAGE_TABLE_LEVEL 1 -static int is_write_protection (void ) +static int is_write_protection (struct kvm_vcpu *vcpu) { -return guest_cr0 () &CR0_WP_MASK ; +return vcpu->cr0 &CR0_WP_MASK ; }static int is_cpuid_PSE36 (void )
@@ -321,7 +321,7 @@ static void nonpaging_flush(struct kvm_v root =kvm_mmu_alloc_page (vcpu,0 );ASSERT (VALID_PAGE (root)); vcpu->mmu.root_hpa = root; -if (is_paging ()) +if (is_paging (vcpu)) root |= (vcpu->cr3 & (CR3_PCD_MASK |CR3_WPT_MASK ));vmcs_writel (GUEST_CR3 , root); }
@@ -614,7 +614,7 @@ static int init_kvm_mmu(struct kvm_vcpuASSERT (vcpu);ASSERT (!VALID_PAGE (vcpu->mmu.root_hpa)); -if (!is_paging ()) +if (!is_paging (vcpu))return nonpaging_init_context (vcpu);else if (is_long_mode ())return paging64_init_context (vcpu);
drivers/kvm/paging_tmpl.h +1 -1
@@ -251,7 +251,7 @@ static int FNAME(fix_write_pf)(struct kv* supervisor write protection is enabled. */ if (!writable_shadow) { -if (is_write_protection ()) +if (is_write_protection (vcpu))return 0 ; *shadow_ent &= ~PT_USER_MASK ; }
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 11/38 KVM: Add get_segment_base() arch accessor
In reply to Avi KivityThis could have been implemented in terms of the existing get_segment(), but that make unnecessary vmx accesses.
drivers/kvm/kvm.h +1 -0
@@ -248,6 +248,7 @@ struct kvm_arch_ops { struct kvm_debug_guest *dbg);int (*get_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 *pdata);int (*set_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 data); +u64 (*get_segment_base)(struct kvm_vcpu *vcpu,int seg);void (*get_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg); void (*set_segment)(struct kvm_vcpu *vcpu,
drivers/kvm/kvm_main.c +14 -7
@@ -1776,12 +1776,19 @@ static int emulator_cmpxchg_emulated(unsreturn emulator_write_emulated (addr, new, bytes, ctxt); } +static unsigned long get_segment_base (struct kvm_vcpu *vcpu,int seg) +{ +return kvm_arch_ops->get_segment_base (vcpu, seg); +} +static void report_emulation_failure (struct x86_emulate_ctxt *ctxt) {static int reported;u8 opcodes[4 ];unsigned long rip =vmcs_readl (GUEST_RIP ); -unsigned long rip_linear = rip +vmcs_readl (GUEST_CS_BASE ); +unsigned long rip_linear; + + rip_linear = rip +get_segment_base (ctxt->vcpu,VCPU_SREG_CS );if (reported)return ;
@@ -1835,14 +1842,14 @@ static int emulate_instruction(struct kv emulate_ctxt.es_base =0 ; emulate_ctxt.ss_base =0 ; }else { - emulate_ctxt.cs_base =vmcs_readl (GUEST_CS_BASE ); - emulate_ctxt.ds_base =vmcs_readl (GUEST_DS_BASE ); - emulate_ctxt.es_base =vmcs_readl (GUEST_ES_BASE ); - emulate_ctxt.ss_base =vmcs_readl (GUEST_SS_BASE ); + emulate_ctxt.cs_base =get_segment_base (vcpu,VCPU_SREG_CS ); + emulate_ctxt.ds_base =get_segment_base (vcpu,VCPU_SREG_DS ); + emulate_ctxt.es_base =get_segment_base (vcpu,VCPU_SREG_ES ); + emulate_ctxt.ss_base =get_segment_base (vcpu,VCPU_SREG_SS ); } - emulate_ctxt.gs_base =vmcs_readl (GUEST_GS_BASE ); - emulate_ctxt.fs_base =vmcs_readl (GUEST_FS_BASE ); + emulate_ctxt.gs_base =get_segment_base (vcpu,VCPU_SREG_GS ); + emulate_ctxt.fs_base =get_segment_base (vcpu,VCPU_SREG_FS ); vcpu->mmio_is_write =0 ; r =x86_emulate_memop (&emulate_ctxt, &emulate_ops);
drivers/kvm/vmx.c +8 -0
@@ -309,6 +309,13 @@ static __exit void hardware_unsetup(voidfree_kvm_area (); } +static u64 vmx_get_segment_base (struct kvm_vcpu *vcpu,int seg) +{ +struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg]; + +return vmcs_readl (sf->base); +} +static void vmx_get_segment (struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg) {
@@ -367,6 +374,7 @@ static struct kvm_arch_ops vmx_arch_ops .set_guest_debug = set_guest_debug, .get_msr = vmx_get_msr, .set_msr = vmx_set_msr, + .get_segment_base = vmx_get_segment_base, .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, };
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 12/38 KVM: Add idt and gdt descriptor accessors
In reply to Avi Kivitydrivers/kvm/kvm.h +9 -0
@@ -236,6 +236,11 @@ struct kvm_stat {u32 irq_exits; }; +struct descriptor_table { +u16 limit; +unsigned long base; +} __attribute__((packed)); +struct kvm_arch_ops {int (*cpu_has_kvm_support)(void );/* __init */ int (*disabled_by_bios)(void );/* __init */
@@ -253,6 +258,10 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg); +void (*get_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt); +void (*set_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt); +void (*get_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt); +void (*set_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt); };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +14 -19
@@ -155,11 +155,6 @@ struct vmx_msr_entry *find_msr_entry(str }EXPORT_SYMBOL_GPL (find_msr_entry); -struct descriptor_table { -u16 limit; -unsigned long base; -} __attribute__((packed)); -static void get_gdt (struct descriptor_table *table) { asm ("sgdt %0" :"=m" (*table));
@@ -2827,6 +2822,7 @@ static void get_segment(struct kvm_vcpustatic int kvm_dev_ioctl_get_sregs (struct kvm *kvm,struct kvm_sregs *sregs) {struct kvm_vcpu *vcpu; +struct descriptor_table dt;if (sregs->vcpu <0 || sregs->vcpu >=KVM_MAX_VCPUS )return -EINVAL ;
@@ -2844,13 +2840,12 @@ static int kvm_dev_ioctl_get_sregs(strucget_segment (vcpu, &sregs->tr,VCPU_SREG_TR );get_segment (vcpu, &sregs->ldt,VCPU_SREG_LDTR ); -#define get_dtable (var, table) \ - sregs->var.limit = vmcs_read32(GUEST_##table##_LIMIT), \ - sregs->var.base = vmcs_readl(GUEST_##table##_BASE) - -get_dtable (idt,IDTR ); -get_dtable (gdt,GDTR ); -#undef get_dtable + kvm_arch_ops->get_idt (vcpu, &dt); + sregs->idt.limit = dt.limit; + sregs->idt.base = dt.base; + kvm_arch_ops->get_gdt (vcpu, &dt); + sregs->gdt.limit = dt.limit; + sregs->gdt.base = dt.base; sregs->cr0 = vcpu->cr0; sregs->cr2 = vcpu->cr2;
@@ -2879,6 +2874,7 @@ static int kvm_dev_ioctl_set_sregs(strucstruct kvm_vcpu *vcpu;int mmu_reset_needed =0 ;int i; +struct descriptor_table dt;if (sregs->vcpu <0 || sregs->vcpu >=KVM_MAX_VCPUS )return -EINVAL ;
@@ -2896,13 +2892,12 @@ static int kvm_dev_ioctl_set_sregs(strucset_segment (vcpu, &sregs->tr,VCPU_SREG_TR );set_segment (vcpu, &sregs->ldt,VCPU_SREG_LDTR ); -#define set_dtable (var, table) \ - vmcs_write32(GUEST_##table##_LIMIT, sregs->var.limit), \ - vmcs_writel(GUEST_##table##_BASE, sregs->var.base) - -set_dtable (idt,IDTR ); -set_dtable (gdt,GDTR ); -#undef set_dtable + dt.limit = sregs->idt.limit; + dt.base = sregs->idt.base; + kvm_arch_ops->set_idt (vcpu, &dt); + dt.limit = sregs->gdt.limit; + dt.base = sregs->gdt.base; + kvm_arch_ops->set_gdt (vcpu, &dt); vcpu->cr2 = sregs->cr2; mmu_reset_needed |= vcpu->cr3 != sregs->cr3;
drivers/kvm/vmx.c +28 -0
@@ -363,6 +363,30 @@ static void vmx_set_segment(struct kvm_vvmcs_write32 (sf->ar_bytes, ar); } +static void vmx_get_idt (struct kvm_vcpu *vcpu,struct descriptor_table *dt) +{ + dt->limit =vmcs_read32 (GUEST_IDTR_LIMIT ); + dt->base =vmcs_readl (GUEST_IDTR_BASE ); +} + +static void vmx_set_idt (struct kvm_vcpu *vcpu,struct descriptor_table *dt) +{ +vmcs_write32 (GUEST_IDTR_LIMIT , dt->limit); +vmcs_writel (GUEST_IDTR_BASE , dt->base); +} + +static void vmx_get_gdt (struct kvm_vcpu *vcpu,struct descriptor_table *dt) +{ + dt->limit =vmcs_read32 (GUEST_GDTR_LIMIT ); + dt->base =vmcs_readl (GUEST_GDTR_BASE ); +} + +static void vmx_set_gdt (struct kvm_vcpu *vcpu,struct descriptor_table *dt) +{ +vmcs_write32 (GUEST_GDTR_LIMIT , dt->limit); +vmcs_writel (GUEST_GDTR_BASE , dt->base); +} +static struct kvm_arch_ops vmx_arch_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios,
@@ -377,6 +401,10 @@ static struct kvm_arch_ops vmx_arch_ops .get_segment_base = vmx_get_segment_base, .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, + .get_idt = vmx_get_idt, + .set_idt = vmx_set_idt, + .get_gdt = vmx_get_gdt, + .set_gdt = vmx_set_gdt, };static int __init vmx_init (void )
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 13/38 KVM: Make syncing the register file to the vcpu structure an arch operation
In reply to Avi KivityThis copies any general purpose guest registers maintained by the hardware to the vcpu structure (and back).
drivers/kvm/kvm.h +2 -0
@@ -262,6 +262,8 @@ struct kvm_arch_ops {void (*set_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*get_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*set_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt); +void (*cache_regs)(struct kvm_vcpu *vcpu); +void (*decache_regs)(struct kvm_vcpu *vcpu); };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +12 -32
105 lines not on this page · raw message
drivers/kvm/vmx.c +22 -0
@@ -180,6 +180,26 @@ static int vmx_set_msr(struct kvm_vcpu *return 0 ; } +/* +* Sync the rsp and rip registers into the vcpu structure. This allows +* registers to be accessed by indexing vcpu->regs. +*/ +static void vcpu_load_rsp_rip (struct kvm_vcpu *vcpu) +{ + vcpu->regs[VCPU_REGS_RSP ] =vmcs_readl (GUEST_RSP ); + vcpu->rip =vmcs_readl (GUEST_RIP ); +} + +/* +* Syncs rsp and rip back into the vmcs. Should be called after possible +* modification. +*/ +static void vcpu_put_rsp_rip (struct kvm_vcpu *vcpu) +{ +vmcs_writel (GUEST_RSP , vcpu->regs[VCPU_REGS_RSP ]); +vmcs_writel (GUEST_RIP , vcpu->rip); +} +static int set_guest_debug (struct kvm_vcpu *vcpu,struct kvm_debug_guest *dbg) {unsigned long dr7 =0x400 ;
@@ -405,6 +425,8 @@ static struct kvm_arch_ops vmx_arch_ops .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt, .set_gdt = vmx_set_gdt, + .cache_regs = vcpu_load_rsp_rip, + .decache_regs = vcpu_put_rsp_rip, };static int __init vmx_init (void )
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 14/38 KVM: Make the vcpu execution loop an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +71 -0
@@ -264,6 +264,9 @@ struct kvm_arch_ops {void (*set_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*cache_regs)(struct kvm_vcpu *vcpu);void (*decache_regs)(struct kvm_vcpu *vcpu); + +int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run); +unsigned long vmx_return;/* temporary hack */ };extern struct kvm_stat kvm_stat;
@@ -306,6 +309,11 @@ unsigned long realmode_get_cr(struct kvmvoid realmode_set_cr (struct kvm_vcpu *vcpu,int cr,unsigned long value,unsigned long *rflags); +void load_msrs (struct vmx_msr_entry *e,int n); +void save_msrs (struct vmx_msr_entry *e,int n); +void kvm_resched (struct kvm_vcpu *vcpu); +int kvm_handle_exit (struct kvm_run *kvm_run,struct kvm_vcpu *vcpu); + int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
@@ -398,6 +406,69 @@ static inline struct kvm_mmu_page *page_return (struct kvm_mmu_page *)page->private; } +static inline u16 read_fs (void ) +{ +u16 seg; + asm ("mov %%fs, %0" :"=g" (seg)); +return seg; +} + +static inline u16 read_gs (void ) +{ +u16 seg; + asm ("mov %%gs, %0" :"=g" (seg)); +return seg; +} + +static inline u16 read_ldt (void ) +{ +u16 ldt; + asm ("sldt %0" :"=g" (ldt)); +return ldt; +} + +static inline void load_fs (u16 sel) +{ + asm ("mov %0, %%fs" : :"rm" (sel)); +} + +static inline void load_gs (u16 sel) +{ + asm ("mov %0, %%gs" : :"rm" (sel)); +} + +#ifndef load_ldt +static inline void load_ldt (u16 sel) +{ + asm ("lldt %0" : :"g" (sel)); +} +#endif + +#ifdef __x86_64__ +static inline unsigned long read_msr (unsigned long msr) +{ +u64 value; + +rdmsrl (msr, value); +return value; +} +#endif + +static inline void fx_save (void *image) +{ + asm ("fxsave (%0)" ::"r" (image)); +} + +static inline void fx_restore (void *image) +{ + asm ("fxrstor (%0)" ::"r" (image)); +} + +static inline void fpu_init (void ) +{ + asm ("finit" ); +} +#define ASM_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30"#define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2"#define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3"
drivers/kvm/kvm_main.c +19 -398
518 lines not on this page · raw message
drivers/kvm/kvm_vmx.h +10 -0
@@ -17,4 +17,14 @@ static inline void vmcs_write64(unsigned #endif } +#ifdef __x86_64__ +/* +* avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt +* mechanism (cpu bug AA24) +*/ +#define NR_BAD_MSRS 2 +#else +#define NR_BAD_MSRS 0 +#endif +#endif
drivers/kvm/vmx.c +327 -0
345 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 15/38 KVM: Move the vmx exit handlers to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm.h +22 -1
@@ -266,6 +266,7 @@ struct kvm_arch_ops {void (*decache_regs)(struct kvm_vcpu *vcpu);int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run); +void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);unsigned long vmx_return;/* temporary hack */ };
@@ -300,6 +301,14 @@ static inline struct page *gfn_to_page(sstruct kvm_memory_slot *gfn_to_memslot (struct kvm *kvm,gfn_t gfn);void mark_page_dirty (struct kvm *kvm,gfn_t gfn); +enum emulation_result { +EMULATE_DONE ,/* no further processing */ +EMULATE_DO_MMIO ,/* kvm_run filled with mmio request */ +EMULATE_FAIL ,/* can't emulate this instruction */ +}; + +int emulate_instruction (struct kvm_vcpu *vcpu,struct kvm_run *run, +unsigned long cr2,u16 error_code);void realmode_lgdt (struct kvm_vcpu *vcpu,u16 size,unsigned long address);void realmode_lidt (struct kvm_vcpu *vcpu,u16 size,unsigned long address); void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
@@ -309,10 +318,22 @@ unsigned long realmode_get_cr(struct kvmvoid realmode_set_cr (struct kvm_vcpu *vcpu,int cr,unsigned long value,unsigned long *rflags); +void set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0); +void set_cr3 (struct kvm_vcpu *vcpu,unsigned long cr0); +void set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr0); +void set_cr8 (struct kvm_vcpu *vcpu,unsigned long cr0); +void lmsw (struct kvm_vcpu *vcpu,unsigned long msw); + +void inject_gp (struct kvm_vcpu *vcpu); + +#ifdef __x86_64__ +void set_efer (struct kvm_vcpu *vcpu,u64 efer); +#endif + +void load_msrs (struct vmx_msr_entry *e,int n);void save_msrs (struct vmx_msr_entry *e,int n);void kvm_resched (struct kvm_vcpu *vcpu); -int kvm_handle_exit (struct kvm_run *kvm_run,struct kvm_vcpu *vcpu); int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr,
drivers/kvm/kvm_main.c +18 -430
553 lines not on this page · raw message
drivers/kvm/vmx.c +408 -3
431 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 16/38 KVM: Make vcpu_setup() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +40 -1
@@ -153,6 +153,17 @@ enum {NR_VCPU_REGS }; +enum { +VCPU_SREG_CS , +VCPU_SREG_DS , +VCPU_SREG_ES , +VCPU_SREG_FS , +VCPU_SREG_GS , +VCPU_SREG_SS , +VCPU_SREG_TR , +VCPU_SREG_LDTR , +}; +struct kvm_vcpu {struct kvm *kvm;struct vmcs *vmcs;
@@ -266,8 +277,8 @@ struct kvm_arch_ops {void (*decache_regs)(struct kvm_vcpu *vcpu);int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run); +int (*vcpu_setup)(struct kvm_vcpu *vcpu);void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); -unsigned long vmx_return;/* temporary hack */ };extern struct kvm_stat kvm_stat;
@@ -324,12 +335,18 @@ void set_cr4(struct kvm_vcpu *vcpu, unsivoid set_cr8 (struct kvm_vcpu *vcpu,unsigned long cr0);void lmsw (struct kvm_vcpu *vcpu,unsigned long msw); +void __set_efer (struct kvm_vcpu *vcpu,u64 efer); +void __set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0); +void __set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr0); + +int rmode_tss_base (struct kvm * kvm);/* temporary hack */ void inject_gp (struct kvm_vcpu *vcpu);#ifdef __x86_64__void set_efer (struct kvm_vcpu *vcpu,u64 efer);#endif +void fx_init (struct kvm_vcpu *vcpu);void load_msrs (struct vmx_msr_entry *e,int n);void save_msrs (struct vmx_msr_entry *e,int n);
@@ -348,6 +365,12 @@ int kvm_write_guest(struct kvm_vcpu *vcpvoid vmcs_writel (unsigned long field,unsigned long value);unsigned long vmcs_readl (unsigned long field); +static inline struct page *_gfn_to_page (struct kvm *kvm,gfn_t gfn) +{ +struct kvm_memory_slot *slot =gfn_to_memslot (kvm, gfn); +return (slot) ? slot->phys_mem[gfn - slot->base_gfn] :0 ; +} +static inline u16 vmcs_read16 (unsigned long field) {return vmcs_readl (field);
@@ -465,6 +488,11 @@ static inline void load_ldt(u16 sel) }#endif +static inline void get_idt (struct descriptor_table *table) +{ + asm ("sidt %0" :"=m" (*table)); +} +#ifdef __x86_64__static inline unsigned long read_msr (unsigned long msr) {
@@ -490,6 +518,11 @@ static inline void fpu_init(void) asm ("finit" ); } +static inline u32 get_rdx_init_val (void ) +{ +return 0x600 ;/* P6 family */ +} +#define ASM_VMX_VMCLEAR_RAX ".byte 0x66, 0x0f, 0xc7, 0x30"#define ASM_VMX_VMLAUNCH ".byte 0x0f, 0x01, 0xc2"#define ASM_VMX_VMRESUME ".byte 0x0f, 0x01, 0xc3"
@@ -502,6 +535,12 @@ static inline void fpu_init(void)#define MSR_IA32_TIME_STAMP_COUNTER 0x010 +#define TSS_IOPB_BASE_OFFSET 0x66 +#define TSS_BASE_SIZE 0x68 +#define TSS_IOPB_SIZE (65536 / 8) +#define TSS_REDIRECTION_SIZE (256 / 8) +#define RMODE_TSS_SIZE (TSS_BASE_SIZE + TSS_REDIRECTION_SIZE + TSS_IOPB_SIZE + 1) +#ifdef __x86_64__/*
drivers/kvm/kvm_main.c +14 -322
438 lines not on this page · raw message
drivers/kvm/vmx.c +279 -3
318 lines not on this page · raw message
drivers/kvm/vmx.h +5 -0
@@ -287,5 +287,10 @@ enum vmcs_field {#define CR4_VMXE 0x2000#define MSR_IA32_VMX_BASIC_MSR 0x480 +#define MSR_IA32_FEATURE_CONTROL 0x03a +#define MSR_IA32_VMX_PINBASED_CTLS_MSR 0x481 +#define MSR_IA32_VMX_PROCBASED_CTLS_MSR 0x482 +#define MSR_IA32_VMX_EXIT_CTLS_MSR 0x483 +#define MSR_IA32_VMX_ENTRY_CTLS_MSR 0x484#endif
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 17/38 KVM: Make __set_cr0() (and dependencies) arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +3 -2
@@ -269,6 +269,7 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg); +void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*get_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*set_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*get_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);
@@ -279,6 +280,8 @@ struct kvm_arch_ops {int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run);int (*vcpu_setup)(struct kvm_vcpu *vcpu);void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); + +void (*update_exception_bitmap)(struct kvm_vcpu *vcpu);/* hack */ };extern struct kvm_stat kvm_stat;
@@ -336,10 +339,8 @@ void set_cr8(struct kvm_vcpu *vcpu, unsivoid lmsw (struct kvm_vcpu *vcpu,unsigned long msw);void __set_efer (struct kvm_vcpu *vcpu,u64 efer); -void __set_cr0 (struct kvm_vcpu *vcpu,unsigned long cr0);void __set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr0); -int rmode_tss_base (struct kvm * kvm);/* temporary hack */ void inject_gp (struct kvm_vcpu *vcpu);#ifdef __x86_64__
drivers/kvm/kvm_main.c +5 -182
219 lines not on this page · raw message
drivers/kvm/vmx.c +175 -1
200 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 18/38 KVM: Make __set_cr4() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +1 -1
@@ -270,6 +270,7 @@ struct kvm_arch_ops {void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0); +void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);void (*get_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*set_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*get_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);
@@ -339,7 +340,6 @@ void set_cr8(struct kvm_vcpu *vcpu, unsivoid lmsw (struct kvm_vcpu *vcpu,unsigned long msw);void __set_efer (struct kvm_vcpu *vcpu,u64 efer); -void __set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr0);void inject_gp (struct kvm_vcpu *vcpu);
drivers/kvm/kvm_main.c +2 -11
@@ -645,15 +645,6 @@ void lmsw(struct kvm_vcpu *vcpu, unsigne }EXPORT_SYMBOL_GPL (lmsw); -void __set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4) -{ -vmcs_writel (CR4_READ_SHADOW , cr4); -vmcs_writel (GUEST_CR4 , cr4 | (vcpu->rmode.active ? -KVM_RMODE_VM_CR4_ALWAYS_ON :KVM_PMODE_VM_CR4_ALWAYS_ON )); - vcpu->cr4 = cr4; -} -EXPORT_SYMBOL_GPL (__set_cr4); -void set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4) {if (cr4 &CR4_RESEVED_BITS ) {
@@ -680,7 +671,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsiinject_gp (vcpu);return ; } -__set_cr4 (vcpu, cr4); + kvm_arch_ops->set_cr4 (vcpu, cr4);spin_lock (&vcpu->kvm->lock);kvm_mmu_reset_context (vcpu);spin_unlock (&vcpu->kvm->lock);
@@ -1624,7 +1615,7 @@ static int kvm_dev_ioctl_set_sregs(struc vcpu->cr0 = sregs->cr0; mmu_reset_needed |= vcpu->cr4 != sregs->cr4; -__set_cr4 (vcpu, sregs->cr4); + kvm_arch_ops->set_cr4 (vcpu, sregs->cr4);if (mmu_reset_needed)kvm_mmu_reset_context (vcpu);
drivers/kvm/vmx.c +10 -1
@@ -545,6 +545,14 @@ static void vmx_set_cr0(struct kvm_vcpu vcpu->cr0 = cr0; } +static void vmx_set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4) +{ +vmcs_writel (CR4_READ_SHADOW , cr4); +vmcs_writel (GUEST_CR4 , cr4 | (vcpu->rmode.active ? +KVM_RMODE_VM_CR4_ALWAYS_ON :KVM_PMODE_VM_CR4_ALWAYS_ON )); + vcpu->cr4 = cr4; +} +static u64 vmx_get_segment_base (struct kvm_vcpu *vcpu,int seg) {struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -872,7 +880,7 @@ static int vmx_vcpu_setup(struct kvm_vcp vcpu->cr0 =0x60000010 ;vmx_set_cr0 (vcpu, vcpu->cr0);// enter rmode -__set_cr4 (vcpu,0 ); +vmx_set_cr4 (vcpu,0 );#ifdef __x86_64____set_efer (vcpu,0 );#endif
@@ -1597,6 +1605,7 @@ static struct kvm_arch_ops vmx_arch_ops .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, .set_cr0 = vmx_set_cr0, + .set_cr4 = vmx_set_cr4, .get_idt = vmx_get_idt, .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 19/38 KVM: Make __set_efer() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +1 -2
@@ -271,6 +271,7 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4); +void (*set_efer)(struct kvm_vcpu *vcpu,u64 efer);void (*get_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*set_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*get_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);
@@ -339,8 +340,6 @@ void set_cr4(struct kvm_vcpu *vcpu, unsivoid set_cr8 (struct kvm_vcpu *vcpu,unsigned long cr0);void lmsw (struct kvm_vcpu *vcpu,unsigned long msw); -void __set_efer (struct kvm_vcpu *vcpu,u64 efer); -void inject_gp (struct kvm_vcpu *vcpu);#ifdef __x86_64__
drivers/kvm/kvm_main.c +1 -26
@@ -525,31 +525,6 @@ void guest_write_tsc(u64 guest_tsc) }EXPORT_SYMBOL_GPL (guest_write_tsc); -#ifdef __x86_64__ - -void __set_efer (struct kvm_vcpu *vcpu,u64 efer) -{ -struct vmx_msr_entry *msr =find_msr_entry (vcpu,MSR_EFER ); - - vcpu->shadow_efer = efer; -if (efer &EFER_LMA ) { -vmcs_write32 (VM_ENTRY_CONTROLS , -vmcs_read32 (VM_ENTRY_CONTROLS ) | -VM_ENTRY_CONTROLS_IA32E_MASK ); - msr->data = efer; - - }else { -vmcs_write32 (VM_ENTRY_CONTROLS , -vmcs_read32 (VM_ENTRY_CONTROLS ) & - ~VM_ENTRY_CONTROLS_IA32E_MASK ); - - msr->data = efer & ~EFER_LME ; - } -} -EXPORT_SYMBOL_GPL (__set_efer); - -#endif -static int pdptrs_have_reserved_bits_set (struct kvm_vcpu *vcpu,unsigned long cr3) {
@@ -1602,7 +1577,7 @@ static int kvm_dev_ioctl_set_sregs(struc mmu_reset_needed |= vcpu->shadow_efer != sregs->efer;#ifdef __x86_64__ -__set_efer (vcpu, sregs->efer); + kvm_arch_ops->set_efer (vcpu, sregs->efer);#endif vcpu->apic_base = sregs->apic_base;
drivers/kvm/vmx.c +26 -1
@@ -553,6 +553,30 @@ static void vmx_set_cr4(struct kvm_vcpu vcpu->cr4 = cr4; } +#ifdef __x86_64__ + +static void vmx_set_efer (struct kvm_vcpu *vcpu,u64 efer) +{ +struct vmx_msr_entry *msr =find_msr_entry (vcpu,MSR_EFER ); + + vcpu->shadow_efer = efer; +if (efer &EFER_LMA ) { +vmcs_write32 (VM_ENTRY_CONTROLS , +vmcs_read32 (VM_ENTRY_CONTROLS ) | +VM_ENTRY_CONTROLS_IA32E_MASK ); + msr->data = efer; + + }else { +vmcs_write32 (VM_ENTRY_CONTROLS , +vmcs_read32 (VM_ENTRY_CONTROLS ) & + ~VM_ENTRY_CONTROLS_IA32E_MASK ); + + msr->data = efer & ~EFER_LME ; + } +} + +#endif +static u64 vmx_get_segment_base (struct kvm_vcpu *vcpu,int seg) {struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
@@ -882,7 +906,7 @@ static int vmx_vcpu_setup(struct kvm_vcpvmx_set_cr0 (vcpu, vcpu->cr0);// enter rmode vmx_set_cr4 (vcpu,0 );#ifdef __x86_64__ -__set_efer (vcpu,0 ); +vmx_set_efer (vcpu,0 );#endif return 0 ;
@@ -1606,6 +1630,7 @@ static struct kvm_arch_ops vmx_arch_ops .set_segment = vmx_set_segment, .set_cr0 = vmx_set_cr0, .set_cr4 = vmx_set_cr4, + .set_efer = vmx_set_efer, .get_idt = vmx_get_idt, .set_idt = vmx_set_idt, .get_gdt = vmx_get_gdt,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
Re: [PATCH 19/38] KVM: Make __set_efer() an arch operation
drivers/kvm/kvm_main.c static int kvm_dev_ioctl_set_sregs(struc · line 1581
Quoted 4 lines · Avi Kivity
#ifdef
__x86_64__drivers/kvm/kvm_main.c +1
-1-__set_efer (vcpu, sregs->efer); + kvm_arch_ops->set_efer (vcpu, sregs->efer);#endif
I think it would be much better to make ->set_efer a noop for 32bit, and have different operation vectors for 32 vs 64 bit.
drivers/kvm/vmx.c static int vmx_vcpu_setup(struct kvm_vcp · line 910
Quoted 4 lines
#ifdef
__x86_64__drivers/kvm/vmx.c +1
-1-__set_efer (vcpu,0 ); +vmx_set_efer (vcpu,0 );#endif
Similarly vmx_set_efer should just become a noop on 32bit.
Re: [PATCH 19/38] KVM: Make __set_efer() an arch operation
Quoted 12 lines · Christoph Hellwig
drivers/kvm/kvm_main.c static int kvm_dev_ioctl_set_sregs(struc · line 1581
Quoted 5 lines · Avi Kivity
#ifdef
__x86_64__drivers/kvm/kvm_main.c +1
-1-__set_efer (vcpu, sregs->efer); + kvm_arch_ops->set_efer (vcpu, sregs->efer);#endif I think it would be much better to make ->set_efer a noop for 32bit, and have different operation vectors for 32 vs 64 bit.
Okay. I'll submit an incremental patch as part of a larger cleanup I'm planning.
Quoted 8 lines
drivers/kvm/vmx.c static int vmx_vcpu_setup(struct kvm_vcp · line 910
Quoted 5 lines
#ifdef
__x86_64__drivers/kvm/vmx.c +1
-1-__set_efer (vcpu,0 ); +vmx_set_efer (vcpu,0 );#endif Similarly
vmx_set_efershould just become a noop on 32bit.
Ok.
Signature · 8 lines
error compiling committee.c: too many arguments to function ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 20/38 KVM: Make set_cr3() and tlb flushing arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +3 -0
@@ -270,6 +270,7 @@ struct kvm_arch_ops {void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0); +void (*set_cr3)(struct kvm_vcpu *vcpu,unsigned long cr3);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);void (*set_efer)(struct kvm_vcpu *vcpu,u64 efer);void (*get_idt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);
@@ -279,6 +280,8 @@ struct kvm_arch_ops {void (*cache_regs)(struct kvm_vcpu *vcpu);void (*decache_regs)(struct kvm_vcpu *vcpu); +void (*flush_tlb)(struct kvm_vcpu *vcpu); +int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run);int (*vcpu_setup)(struct kvm_vcpu *vcpu);void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
drivers/kvm/mmu.c +5 -7
@@ -323,7 +323,7 @@ static void nonpaging_flush(struct kvm_v vcpu->mmu.root_hpa = root;if (is_paging (vcpu)) root |= (vcpu->cr3 & (CR3_PCD_MASK |CR3_WPT_MASK )); -vmcs_writel (GUEST_CR3 , root); + kvm_arch_ops->set_cr3 (vcpu, root); }static gpa_t nonpaging_gva_to_gpa (struct kvm_vcpu *vcpu,gva_t vaddr)
@@ -386,7 +386,7 @@ static int nonpaging_init_context(struct context->shadow_root_level =PT32E_ROOT_LEVEL ; context->root_hpa =kvm_mmu_alloc_page (vcpu,0 );ASSERT (VALID_PAGE (context->root_hpa)); -vmcs_writel (GUEST_CR3 , context->root_hpa); + kvm_arch_ops->set_cr3 (vcpu, context->root_hpa);return 0 ; }
@@ -539,9 +539,7 @@ static void paging_inval_page(struct kvm table[index] =0 ;release_pt_page_64 (vcpu, page_addr,PT_PAGE_TABLE_LEVEL ); -//flush tlb -vmcs_writel (GUEST_CR3 , vcpu->mmu.root_hpa | - (vcpu->cr3 & (CR3_PCD_MASK |CR3_WPT_MASK ))); + kvm_arch_ops->flush_tlb (vcpu);return ; } }
@@ -574,7 +572,7 @@ static int paging64_init_context(struct context->shadow_root_level =PT64_ROOT_LEVEL ; context->root_hpa =kvm_mmu_alloc_page (vcpu,0 );ASSERT (VALID_PAGE (context->root_hpa)); -vmcs_writel (GUEST_CR3 , context->root_hpa | + kvm_arch_ops->set_cr3 (vcpu, context->root_hpa | (vcpu->cr3 & (CR3_PCD_MASK |CR3_WPT_MASK )));return 0 ; }
@@ -592,7 +590,7 @@ static int paging32_init_context(struct context->shadow_root_level =PT32E_ROOT_LEVEL ; context->root_hpa =kvm_mmu_alloc_page (vcpu,0 );ASSERT (VALID_PAGE (context->root_hpa)); -vmcs_writel (GUEST_CR3 , context->root_hpa | + kvm_arch_ops->set_cr3 (vcpu, context->root_hpa | (vcpu->cr3 & (CR3_PCD_MASK |CR3_WPT_MASK )));return 0 ; }
drivers/kvm/vmx.c +13 -0
@@ -545,6 +545,11 @@ static void vmx_set_cr0(struct kvm_vcpu vcpu->cr0 = cr0; } +static void vmx_set_cr3 (struct kvm_vcpu *vcpu,unsigned long cr3) +{ +vmcs_writel (GUEST_CR3 , cr3); +} +static void vmx_set_cr4 (struct kvm_vcpu *vcpu,unsigned long cr4) {vmcs_writel (CR4_READ_SHADOW , cr4);
@@ -1614,6 +1619,11 @@ again:return 0 ; } +static void vmx_flush_tlb (struct kvm_vcpu *vcpu) +{ +vmcs_writel (GUEST_CR3 ,vmcs_readl (GUEST_CR3 )); +} +static struct kvm_arch_ops vmx_arch_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios,
@@ -1629,6 +1639,7 @@ static struct kvm_arch_ops vmx_arch_ops .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, .set_cr0 = vmx_set_cr0, + .set_cr3 = vmx_set_cr3, .set_cr4 = vmx_set_cr4, .set_efer = vmx_set_efer, .get_idt = vmx_get_idt,
@@ -1638,6 +1649,8 @@ static struct kvm_arch_ops vmx_arch_ops .cache_regs = vcpu_load_rsp_rip, .decache_regs = vcpu_put_rsp_rip, + .flush_tlb = vmx_flush_tlb, + .run = vmx_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction, .vcpu_setup = vmx_vcpu_setup,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 21/38 KVM: Make inject_page_fault() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -0
@@ -281,6 +281,8 @@ struct kvm_arch_ops {void (*decache_regs)(struct kvm_vcpu *vcpu);void (*flush_tlb)(struct kvm_vcpu *vcpu); +void (*inject_page_fault)(struct kvm_vcpu *vcpu, +unsigned long addr,u32 err_code);int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run);int (*vcpu_setup)(struct kvm_vcpu *vcpu);
drivers/kvm/mmu.c +1 -26
@@ -455,32 +455,7 @@ static void inject_page_fault(struct kvm u64 addr, u32 err_code) { -u32 vect_info =vmcs_read32 (IDT_VECTORING_INFO_FIELD ); - -pgprintk ("inject_page_fault: 0x%llx err 0x%x\n" , addr, err_code); - - ++kvm_stat.pf_guest; - -if (is_page_fault (vect_info)) { -printk (KERN_DEBUG "inject_page_fault: " -"double fault 0x%llx @ 0x%lx\n" , - addr,vmcs_readl (GUEST_RIP )); -vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE ,0 ); -vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , -DF_VECTOR | -INTR_TYPE_EXCEPTION | -INTR_INFO_DELIEVER_CODE_MASK | -INTR_INFO_VALID_MASK ); -return ; - } - vcpu->cr2 = addr; -vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE , err_code); -vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , -PF_VECTOR | -INTR_TYPE_EXCEPTION | -INTR_INFO_DELIEVER_CODE_MASK | -INTR_INFO_VALID_MASK ); - + kvm_arch_ops->inject_page_fault (vcpu, addr, err_code); }static inline int fix_read_pf (u64 *shadow_ent)
drivers/kvm/vmx.c +31 -0
@@ -1624,6 +1624,36 @@ static void vmx_flush_tlb(struct kvm_vcpvmcs_writel (GUEST_CR3 ,vmcs_readl (GUEST_CR3 )); } +static void vmx_inject_page_fault (struct kvm_vcpu *vcpu, +unsigned long addr, +u32 err_code) +{ +u32 vect_info =vmcs_read32 (IDT_VECTORING_INFO_FIELD ); + + ++kvm_stat.pf_guest; + +if (is_page_fault (vect_info)) { +printk (KERN_DEBUG "inject_page_fault: " +"double fault 0x%lx @ 0x%lx\n" , + addr,vmcs_readl (GUEST_RIP )); +vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE ,0 ); +vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , +DF_VECTOR | +INTR_TYPE_EXCEPTION | +INTR_INFO_DELIEVER_CODE_MASK | +INTR_INFO_VALID_MASK ); +return ; + } + vcpu->cr2 = addr; +vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE , err_code); +vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , +PF_VECTOR | +INTR_TYPE_EXCEPTION | +INTR_INFO_DELIEVER_CODE_MASK | +INTR_INFO_VALID_MASK ); + +} +static struct kvm_arch_ops vmx_arch_ops = { .cpu_has_kvm_support = cpu_has_kvm_support, .disabled_by_bios = vmx_disabled_by_bios,
@@ -1650,6 +1680,7 @@ static struct kvm_arch_ops vmx_arch_ops .decache_regs = vcpu_put_rsp_rip, .flush_tlb = vmx_flush_tlb, + .inject_page_fault = vmx_inject_page_fault, .run = vmx_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 22/38 KVM: Make inject_gp() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -2
@@ -284,6 +284,8 @@ struct kvm_arch_ops {void (*inject_page_fault)(struct kvm_vcpu *vcpu,unsigned long addr,u32 err_code); +void (*inject_gp)(struct kvm_vcpu *vcpu,unsigned err_code); +int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run);int (*vcpu_setup)(struct kvm_vcpu *vcpu);void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu);
@@ -345,8 +347,6 @@ void set_cr4(struct kvm_vcpu *vcpu, unsivoid set_cr8 (struct kvm_vcpu *vcpu,unsigned long cr0);void lmsw (struct kvm_vcpu *vcpu,unsigned long msw); -void inject_gp (struct kvm_vcpu *vcpu); -#ifdef __x86_64__void set_efer (struct kvm_vcpu *vcpu,u64 efer);#endif
drivers/kvm/kvm_main.c +2 -10
@@ -485,18 +485,10 @@ void vmcs_writel(unsigned long field, un }EXPORT_SYMBOL_GPL (vmcs_writel); -void inject_gp (struct kvm_vcpu *vcpu) +static void inject_gp (struct kvm_vcpu *vcpu) { -printk (KERN_DEBUG "inject_general_protection: rip 0x%lx\n" , -vmcs_readl (GUEST_RIP )); -vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE ,0 ); -vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , -GP_VECTOR | -INTR_TYPE_EXCEPTION | -INTR_INFO_DELIEVER_CODE_MASK | -INTR_INFO_VALID_MASK ); + kvm_arch_ops->inject_gp (vcpu,0 ); } -EXPORT_SYMBOL_GPL (inject_gp);/* * reads and returns guest's timestamp counter "register"
drivers/kvm/vmx.c +16 -2
@@ -80,6 +80,18 @@ static void skip_emulated_instruction(st interruptibility & ~3); } +static void vmx_inject_gp (struct kvm_vcpu *vcpu,unsigned error_code) +{ +printk (KERN_DEBUG "inject_general_protection: rip 0x%lx\n" , +vmcs_readl (GUEST_RIP )); +vmcs_write32 (VM_ENTRY_EXCEPTION_ERROR_CODE , error_code); +vmcs_write32 (VM_ENTRY_INTR_INFO_FIELD , +GP_VECTOR | +INTR_TYPE_EXCEPTION | +INTR_INFO_DELIEVER_CODE_MASK | +INTR_INFO_VALID_MASK ); +} +static void reload_tss (void ) {#ifndef __x86_64__
@@ -1318,7 +1330,7 @@ static int handle_rdmsr(struct kvm_vcpuu64 data;if (vmx_get_msr (vcpu, ecx, &data)) { -inject_gp (vcpu); +vmx_inject_gp (vcpu,0 );return 1 ; }
@@ -1336,7 +1348,7 @@ static int handle_wrmsr(struct kvm_vcpu | ((u64)(vcpu->regs[VCPU_REGS_RDX] & -1u) << 32);if (vmx_set_msr (vcpu, ecx, data) !=0 ) { -inject_gp (vcpu); +vmx_inject_gp (vcpu,0 );return 1 ; }
@@ -1682,6 +1694,8 @@ static struct kvm_arch_ops vmx_arch_ops .flush_tlb = vmx_flush_tlb, .inject_page_fault = vmx_inject_page_fault, + .inject_gp = vmx_inject_gp, + .run = vmx_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction, .vcpu_setup = vmx_vcpu_setup,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 23/38 KVM: Use the idt and gdt accessors in realmode emulation
In reply to Avi Kivitydrivers/kvm/kvm_main.c +6 -4
@@ -1225,14 +1225,16 @@ static u64 mk_cr_64(u64 curr_cr, u32 newvoid realmode_lgdt (struct kvm_vcpu *vcpu,u16 limit,unsigned long base) { -vmcs_writel (GUEST_GDTR_BASE , base); -vmcs_write32 (GUEST_GDTR_LIMIT , limit); +struct descriptor_table dt = { limit, base }; + + kvm_arch_ops->set_gdt (vcpu, &dt); }void realmode_lidt (struct kvm_vcpu *vcpu,u16 limit,unsigned long base) { -vmcs_writel (GUEST_IDTR_BASE , base); -vmcs_write32 (GUEST_IDTR_LIMIT , limit); +struct descriptor_table dt = { limit, base }; + + kvm_arch_ops->set_idt (vcpu, &dt); } void realmode_lmsw(struct kvm_vcpu *vcpu, unsigned long msw,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 24/38 KVM: Use the general purpose register accessors rather than direct access
In reply to Avi Kivitydrivers/kvm/kvm_main.c +9 -5
@@ -1130,7 +1130,7 @@ static void report_emulation_failure(str {static int reported;u8 opcodes[4 ]; -unsigned long rip =vmcs_readl (GUEST_RIP ); +unsigned long rip = ctxt->vcpu->rip;unsigned long rip_linear; rip_linear = rip +get_segment_base (ctxt->vcpu,VCPU_SREG_CS );
@@ -1406,13 +1406,15 @@ static int kvm_dev_ioctl_get_regs(structif (!vcpu)return -ENOENT ; + kvm_arch_ops->cache_regs (vcpu); + regs->rax = vcpu->regs[VCPU_REGS_RAX ]; regs->rbx = vcpu->regs[VCPU_REGS_RBX ]; regs->rcx = vcpu->regs[VCPU_REGS_RCX ]; regs->rdx = vcpu->regs[VCPU_REGS_RDX ]; regs->rsi = vcpu->regs[VCPU_REGS_RSI ]; regs->rdi = vcpu->regs[VCPU_REGS_RDI ]; - regs->rsp =vmcs_readl (GUEST_RSP ); + regs->rsp = vcpu->regs[VCPU_REGS_RSP ]; regs->rbp = vcpu->regs[VCPU_REGS_RBP ];#ifdef __x86_64__ regs->r8 = vcpu->regs[VCPU_REGS_R8 ];
@@ -1425,7 +1427,7 @@ static int kvm_dev_ioctl_get_regs(struct regs->r15 = vcpu->regs[VCPU_REGS_R15 ];#endif - regs->rip =vmcs_readl (GUEST_RIP ); + regs->rip = vcpu->rip; regs->rflags =vmcs_readl (GUEST_RFLAGS );/*
@@ -1456,7 +1458,7 @@ static int kvm_dev_ioctl_set_regs(struct vcpu->regs[VCPU_REGS_RDX ] = regs->rdx; vcpu->regs[VCPU_REGS_RSI ] = regs->rsi; vcpu->regs[VCPU_REGS_RDI ] = regs->rdi; -vmcs_writel (GUEST_RSP , regs->rsp); + vcpu->regs[VCPU_REGS_RSP ] = regs->rsp; vcpu->regs[VCPU_REGS_RBP ] = regs->rbp;#ifdef __x86_64__ vcpu->regs[VCPU_REGS_R8 ] = regs->r8;
@@ -1469,9 +1471,11 @@ static int kvm_dev_ioctl_set_regs(struct vcpu->regs[VCPU_REGS_R15 ] = regs->r15;#endif -vmcs_writel (GUEST_RIP , regs->rip); + vcpu->rip = regs->rip;vmcs_writel (GUEST_RFLAGS , regs->rflags); + kvm_arch_ops->decache_regs (vcpu); +vcpu_put (vcpu);return 0 ;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 25/38 KVM: Move the vmx tsc accessors to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm_main.c +0 -27
@@ -490,33 +490,6 @@ static void inject_gp(struct kvm_vcpu *v kvm_arch_ops->inject_gp (vcpu,0 ); } -/* -* reads and returns guest's timestamp counter "register" -* guest_tsc = host_tsc + tsc_offset -- 21.3 -*/ -u64 guest_read_tsc (void ) -{ -u64 host_tsc, tsc_offset; - -rdtscll (host_tsc); - tsc_offset =vmcs_read64 (TSC_OFFSET ); -return host_tsc + tsc_offset; -} -EXPORT_SYMBOL_GPL (guest_read_tsc); - -/* -* writes 'guest_tsc' into guest's timestamp counter "register" -* guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc -*/ -void guest_write_tsc (u64 guest_tsc) -{ -u64 host_tsc; - -rdtscll (host_tsc); -vmcs_write64 (TSC_OFFSET , guest_tsc - host_tsc); -} -EXPORT_SYMBOL_GPL (guest_write_tsc); -static int pdptrs_have_reserved_bits_set (struct kvm_vcpu *vcpu,unsigned long cr3) {
drivers/kvm/vmx.c +25 -2
@@ -57,8 +57,6 @@ static const u32 vmx_msr_index[] = { };#define NR_VMX_MSR (sizeof(vmx_msr_index) / sizeof(*vmx_msr_index)) -u64 guest_read_tsc (void ); -void guest_write_tsc (u64 guest_tsc);struct vmx_msr_entry *find_msr_entry (struct kvm_vcpu *vcpu,u32 msr);static void skip_emulated_instruction (struct kvm_vcpu *vcpu)
@@ -92,6 +90,31 @@ static void vmx_inject_gp(struct kvm_vcp INTR_INFO_VALID_MASK); } +/* +* reads and returns guest's timestamp counter "register" +* guest_tsc = host_tsc + tsc_offset -- 21.3 +*/ +static u64 guest_read_tsc (void ) +{ +u64 host_tsc, tsc_offset; + +rdtscll (host_tsc); + tsc_offset =vmcs_read64 (TSC_OFFSET ); +return host_tsc + tsc_offset; +} + +/* +* writes 'guest_tsc' into guest's timestamp counter "register" +* guest_tsc = host_tsc + tsc_offset ==> tsc_offset = guest_tsc - host_tsc +*/ +static void guest_write_tsc (u64 guest_tsc) +{ +u64 host_tsc; + +rdtscll (host_tsc); +vmcs_write64 (TSC_OFFSET , guest_tsc - host_tsc); +} +static void reload_tss (void ) {#ifndef __x86_64__
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 26/38 KVM: Access rflags through an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +2 -0
@@ -279,6 +279,8 @@ struct kvm_arch_ops {void (*set_gdt)(struct kvm_vcpu *vcpu,struct descriptor_table *dt);void (*cache_regs)(struct kvm_vcpu *vcpu);void (*decache_regs)(struct kvm_vcpu *vcpu); +unsigned long (*get_rflags)(struct kvm_vcpu *vcpu); +void (*set_rflags)(struct kvm_vcpu *vcpu,unsigned long rflags);void (*flush_tlb)(struct kvm_vcpu *vcpu); void (*inject_page_fault)(struct kvm_vcpu *vcpu,
drivers/kvm/kvm_main.c +6 -6
@@ -1141,7 +1141,7 @@ int emulate_instruction(struct kvm_vcpu cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); emulate_ctxt.vcpu = vcpu; - emulate_ctxt.eflags =vmcs_readl (GUEST_RFLAGS ); + emulate_ctxt.eflags = kvm_arch_ops->get_rflags (vcpu); emulate_ctxt.cr2 = cr2; emulate_ctxt.mode = (emulate_ctxt.eflags &X86_EFLAGS_VM ) ?X86EMUL_MODE_REAL : (cs_ar &AR_L_MASK )
@@ -1182,7 +1182,7 @@ int emulate_instruction(struct kvm_vcpu } kvm_arch_ops->decache_regs (vcpu); -vmcs_writel (GUEST_RFLAGS , emulate_ctxt.eflags); + kvm_arch_ops->set_rflags (vcpu, emulate_ctxt.eflags);if (vcpu->mmio_is_write)return EMULATE_DO_MMIO ;
@@ -1214,7 +1214,7 @@ void realmode_lmsw(struct kvm_vcpu *vcpu unsigned long *rflags) {lmsw (vcpu, msw); - *rflags =vmcs_readl (GUEST_RFLAGS ); + *rflags = kvm_arch_ops->get_rflags (vcpu); }unsigned long realmode_get_cr (struct kvm_vcpu *vcpu,int cr)
@@ -1240,7 +1240,7 @@ void realmode_set_cr(struct kvm_vcpu *vcswitch (cr) {case 0 :set_cr0 (vcpu,mk_cr_64 (vcpu->cr0, val)); - *rflags =vmcs_readl (GUEST_RFLAGS ); + *rflags = kvm_arch_ops->get_rflags (vcpu);break ;case 2 : vcpu->cr2 = val;
@@ -1401,7 +1401,7 @@ static int kvm_dev_ioctl_get_regs(struct#endif regs->rip = vcpu->rip; - regs->rflags =vmcs_readl (GUEST_RFLAGS ); + regs->rflags = kvm_arch_ops->get_rflags (vcpu);/* * Don't leak debug flags in case they were set for guest debugging
@@ -1445,7 +1445,7 @@ static int kvm_dev_ioctl_set_regs(struct#endif vcpu->rip = regs->rip; -vmcs_writel (GUEST_RFLAGS , regs->rflags); + kvm_arch_ops->set_rflags (vcpu, regs->rflags); kvm_arch_ops->decache_regs (vcpu);
drivers/kvm/vmx.c +12 -0
@@ -59,6 +59,16 @@ static const u32 vmx_msr_index[] = {struct vmx_msr_entry *find_msr_entry (struct kvm_vcpu *vcpu,u32 msr); +static unsigned long vmx_get_rflags (struct kvm_vcpu *vcpu) +{ +return vmcs_readl (GUEST_RFLAGS ); +} + +static void vmx_set_rflags (struct kvm_vcpu *vcpu,unsigned long rflags) +{ +vmcs_writel (GUEST_RFLAGS , rflags); +} +static void skip_emulated_instruction (struct kvm_vcpu *vcpu) {unsigned long rip;
@@ -1713,6 +1723,8 @@ static struct kvm_arch_ops vmx_arch_ops .set_gdt = vmx_set_gdt, .cache_regs = vcpu_load_rsp_rip, .decache_regs = vcpu_put_rsp_rip, + .get_rflags = vmx_get_rflags, + .set_rflags = vmx_set_rflags, .flush_tlb = vmx_flush_tlb, .inject_page_fault = vmx_inject_page_fault,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 27/38 KVM: Move the vmx segment field definitions to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm_main.c +0 -25
@@ -65,31 +65,6 @@ static struct kvm_stats_debugfs_item {static struct dentry *debugfs_dir; -#define VMX_SEGMENT_FIELD (seg) \ - [VCPU_SREG_##seg] { \ - GUEST_##seg##_SELECTOR, \ - GUEST_##seg##_BASE, \ - GUEST_##seg##_LIMIT, \ - GUEST_##seg##_AR_BYTES, \ - } - -struct kvm_vmx_segment_field { -unsigned selector; -unsigned base; -unsigned limit; -unsigned ar_bytes; -} kvm_vmx_segment_fields[] = { -VMX_SEGMENT_FIELD (CS ), -VMX_SEGMENT_FIELD (DS ), -VMX_SEGMENT_FIELD (ES ), -VMX_SEGMENT_FIELD (FS ), -VMX_SEGMENT_FIELD (GS ), -VMX_SEGMENT_FIELD (SS ), -VMX_SEGMENT_FIELD (TR ), -VMX_SEGMENT_FIELD (LDTR ), -}; -EXPORT_SYMBOL_GPL (kvm_vmx_segment_fields); -#define MAX_IO_MSRS 256#define CR0_RESEVED_BITS 0xffffffff1ffaffc0ULL
drivers/kvm/vmx.c +19 -2
@@ -42,12 +42,29 @@ extern struct vmcs_descriptor {u32 revision_id; } vmcs_descriptor; -extern struct kvm_vmx_segment_field { +#define VMX_SEGMENT_FIELD (seg) \ + [VCPU_SREG_##seg] { \ + GUEST_##seg##_SELECTOR, \ + GUEST_##seg##_BASE, \ + GUEST_##seg##_LIMIT, \ + GUEST_##seg##_AR_BYTES, \ + } + +static struct kvm_vmx_segment_field {unsigned selector;unsigned base;unsigned limit;unsigned ar_bytes; -} kvm_vmx_segment_fields[]; +} kvm_vmx_segment_fields[] = { +VMX_SEGMENT_FIELD (CS ), +VMX_SEGMENT_FIELD (DS ), +VMX_SEGMENT_FIELD (ES ), +VMX_SEGMENT_FIELD (FS ), +VMX_SEGMENT_FIELD (GS ), +VMX_SEGMENT_FIELD (SS ), +VMX_SEGMENT_FIELD (TR ), +VMX_SEGMENT_FIELD (LDTR ), +};static const u32 vmx_msr_index[] = { #ifdef __x86_64__
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 28/38 KVM: Add an arch accessor for cs d/b and l bits
In reply to Avi KivityThese are used for detecting the current processor mode.
drivers/kvm/kvm.h +1 -0
@@ -269,6 +269,7 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);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);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0);void (*set_cr3)(struct kvm_vcpu *vcpu,unsigned long cr3);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);
drivers/kvm/kvm_main.c +8 -7
@@ -517,15 +517,16 @@ void set_cr0(struct kvm_vcpu *vcpu, unsiif (!is_paging (vcpu) && (cr0 &CR0_PG_MASK )) {#ifdef __x86_64__if ((vcpu->shadow_efer &EFER_LME )) { -u32 guest_cs_ar; +int cs_db, cs_l; +if (!is_pae (vcpu)) {printk (KERN_DEBUG "set_cr0: #GP, start paging " "in long mode while PAE is disabled\n" );inject_gp (vcpu);return ; } - guest_cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); -if (guest_cs_ar &SEGMENT_AR_L_MASK ) { + kvm_arch_ops->get_cs_db_l_bits (vcpu, &cs_db, &cs_l); +if (cs_l) {printk (KERN_DEBUG "set_cr0: #GP, start paging " "in long mode while CS.L == 1\n" );inject_gp (vcpu);
@@ -1109,18 +1110,18 @@ int emulate_instruction(struct kvm_vcpu {struct x86_emulate_ctxt emulate_ctxt;int r; -u32 cs_ar; +int cs_db, cs_l; kvm_arch_ops->cache_regs (vcpu); - cs_ar =vmcs_read32 (GUEST_CS_AR_BYTES ); + kvm_arch_ops->get_cs_db_l_bits (vcpu, &cs_db, &cs_l); emulate_ctxt.vcpu = vcpu; emulate_ctxt.eflags = kvm_arch_ops->get_rflags (vcpu); emulate_ctxt.cr2 = cr2; emulate_ctxt.mode = (emulate_ctxt.eflags &X86_EFLAGS_VM ) - ?X86EMUL_MODE_REAL : (cs_ar &AR_L_MASK ) - ?X86EMUL_MODE_PROT64 : (cs_ar &AR_DB_MASK ) + ?X86EMUL_MODE_REAL : cs_l + ?X86EMUL_MODE_PROT64 : cs_db ?X86EMUL_MODE_PROT32 :X86EMUL_MODE_PROT16 ;if (emulate_ctxt.mode ==X86EMUL_MODE_PROT64 ) {
drivers/kvm/vmx.c +9 -0
@@ -698,6 +698,14 @@ static void vmx_set_segment(struct kvm_vvmcs_write32 (sf->ar_bytes, ar); } +static void vmx_get_cs_db_l_bits (struct kvm_vcpu *vcpu,int *db,int *l) +{ +u32 ar =vmcs_read32 (GUEST_CS_AR_BYTES ); + + *db = (ar >>14 ) &1 ; + *l = (ar >>13 ) &1 ; +} +static void vmx_get_idt (struct kvm_vcpu *vcpu,struct descriptor_table *dt) { dt->limit =vmcs_read32 (GUEST_IDTR_LIMIT );
@@ -1730,6 +1738,7 @@ static struct kvm_arch_ops vmx_arch_ops .get_segment_base = vmx_get_segment_base, .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, + .get_cs_db_l_bits = vmx_get_cs_db_l_bits, .set_cr0 = vmx_set_cr0, .set_cr3 = vmx_set_cr3, .set_cr4 = vmx_set_cr4,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 29/38 KVM: Add a set_cr0_no_modeswitch() arch accessor
In reply to Avi KivityA side effect of using vm86 mode to simulate real mode is that we mangle the segment registers on mode switching. The new set_cr0_no_modeswitch() accessor avoids the mangling when the restore is due to loading the virtual machine from a file.
drivers/kvm/kvm.h +2 -2
@@ -271,6 +271,8 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu,int *db,int *l);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0); +void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu, +unsigned long cr0);void (*set_cr3)(struct kvm_vcpu *vcpu,unsigned long cr3);void (*set_cr4)(struct kvm_vcpu *vcpu,unsigned long cr4);void (*set_efer)(struct kvm_vcpu *vcpu,u64 efer);
@@ -292,8 +294,6 @@ struct kvm_arch_ops {int (*run)(struct kvm_vcpu *vcpu,struct kvm_run *run);int (*vcpu_setup)(struct kvm_vcpu *vcpu);void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); - -void (*update_exception_bitmap)(struct kvm_vcpu *vcpu);/* hack */ };extern struct kvm_stat kvm_stat;
drivers/kvm/kvm_main.c +1 -6
@@ -1529,12 +1529,7 @@ static int kvm_dev_ioctl_set_sregs(struc vcpu->apic_base = sregs->apic_base; mmu_reset_needed |= vcpu->cr0 != sregs->cr0; - vcpu->rmode.active = ((sregs->cr0 &CR0_PE_MASK ) ==0 ); - kvm_arch_ops->update_exception_bitmap (vcpu); -vmcs_writel (CR0_READ_SHADOW , sregs->cr0); -vmcs_writel (GUEST_CR0 , - (sregs->cr0 & ~KVM_GUEST_CR0_MASK ) |KVM_VM_CR0_ALWAYS_ON ); - vcpu->cr0 = sregs->cr0; + kvm_arch_ops->set_cr0_no_modeswitch (vcpu, sregs->cr0); mmu_reset_needed |= vcpu->cr4 != sregs->cr4; kvm_arch_ops->set_cr4 (vcpu, sregs->cr4);
drivers/kvm/vmx.c +14 -2
@@ -607,6 +607,19 @@ static void vmx_set_cr0(struct kvm_vcpu vcpu->cr0 = cr0; } +/* +* Used when restoring the VM to avoid corrupting segment registers +*/ +static void vmx_set_cr0_no_modeswitch (struct kvm_vcpu *vcpu,unsigned long cr0) +{ + vcpu->rmode.active = ((cr0 &CR0_PE_MASK ) ==0 ); +update_exception_bitmap (vcpu); +vmcs_writel (CR0_READ_SHADOW , cr0); +vmcs_writel (GUEST_CR0 , + (cr0 & ~KVM_GUEST_CR0_MASK ) |KVM_VM_CR0_ALWAYS_ON ); + vcpu->cr0 = cr0; +} +static void vmx_set_cr3 (struct kvm_vcpu *vcpu,unsigned long cr3) {vmcs_writel (GUEST_CR3 , cr3);
@@ -1740,6 +1753,7 @@ static struct kvm_arch_ops vmx_arch_ops .set_segment = vmx_set_segment, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, .set_cr0 = vmx_set_cr0, + .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch, .set_cr3 = vmx_set_cr3, .set_cr4 = vmx_set_cr4, .set_efer = vmx_set_efer,
@@ -1760,8 +1774,6 @@ static struct kvm_arch_ops vmx_arch_ops .run = vmx_vcpu_run, .skip_emulated_instruction = skip_emulated_instruction, .vcpu_setup = vmx_vcpu_setup, - - .update_exception_bitmap = update_exception_bitmap, };static int __init vmx_init (void )
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 30/38 KVM: Make vcpu_load() and vcpu_put() arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +19 -0
@@ -260,6 +260,9 @@ struct kvm_arch_ops {int (*hardware_setup)(void );/* __init */ void (*hardware_unsetup)(void );/* __exit */ +struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu); +void (*vcpu_put)(struct kvm_vcpu *vcpu); +int (*set_guest_debug)(struct kvm_vcpu *vcpu,struct kvm_debug_guest *dbg);int (*get_msr)(struct kvm_vcpu *vcpu,u32 msr_index,u64 *pdata);
@@ -296,6 +299,8 @@ struct kvm_arch_ops {void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); }; +void __vcpu_clear (void *arg);/* temporary hack */ +extern struct kvm_stat kvm_stat;extern struct kvm_arch_ops *kvm_arch_ops;
@@ -373,6 +378,8 @@ int kvm_write_guest(struct kvm_vcpu *vcpvoid vmcs_writel (unsigned long field,unsigned long value);unsigned long vmcs_readl (unsigned long field); +unsigned long segment_base (u16 selector); +static inline struct page *_gfn_to_page (struct kvm *kvm,gfn_t gfn) {struct kvm_memory_slot *slot =gfn_to_memslot (kvm, gfn);
@@ -501,6 +508,18 @@ static inline void get_idt(struct descri asm ("sidt %0" :"=m" (*table)); } +static inline void get_gdt (struct descriptor_table *table) +{ + asm ("sgdt %0" :"=m" (*table)); +} + +static inline unsigned long read_tr_base (void ) +{ +u16 tr; + asm ("str %0" :"=g" (tr)); +return segment_base (tr); +} +#ifdef __x86_64__static inline unsigned long read_msr (unsigned long msr) {
drivers/kvm/kvm_main.c +9 -64
128 lines not on this page · raw message
drivers/kvm/vmx.c +56 -0
74 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 31/38 KVM: Make vcpu creation and destruction arch operations
In reply to Avi Kivitydrivers/kvm/kvm.h +3 -2
@@ -260,6 +260,9 @@ struct kvm_arch_ops {int (*hardware_setup)(void );/* __init */ void (*hardware_unsetup)(void );/* __exit */ +int (*vcpu_create)(struct kvm_vcpu *vcpu); +void (*vcpu_free)(struct kvm_vcpu *vcpu); +struct kvm_vcpu *(*vcpu_load)(struct kvm_vcpu *vcpu);void (*vcpu_put)(struct kvm_vcpu *vcpu);
@@ -299,8 +302,6 @@ struct kvm_arch_ops {void (*skip_emulated_instruction)(struct kvm_vcpu *vcpu); }; -void __vcpu_clear (void *arg);/* temporary hack */ -extern struct kvm_stat kvm_stat;extern struct kvm_arch_ops *kvm_arch_ops;
drivers/kvm/kvm_main.c +4 -70
113 lines not on this page · raw message
drivers/kvm/vmx.c +78 -1
103 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 32/38 KVM: Move vmcs static variables to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm_main.c +0 -12
@@ -138,18 +138,6 @@ unsigned long segment_base(u16 selector) }EXPORT_SYMBOL_GPL (segment_base); -DEFINE_PER_CPU(struct vmcs *, vmxarea); -EXPORT_SYMBOL_GPL (per_cpu__vmxarea);/* temporary hack */ -DEFINE_PER_CPU(struct vmcs *, current_vmcs); -EXPORT_SYMBOL_GPL (per_cpu__current_vmcs);/* temporary hack */ - -struct vmcs_descriptor { -int size; -int order; -u32 revision_id; -} vmcs_descriptor; -EXPORT_SYMBOL_GPL (vmcs_descriptor); - int kvm_read_guest(struct kvm_vcpu *vcpu, gva_t addr, unsigned long size,
drivers/kvm/vmx.c +3 -3
@@ -28,8 +28,8 @@MODULE_AUTHOR ("Qumranet" );MODULE_LICENSE ("GPL" ); -DECLARE_PER_CPU(struct vmcs *, vmxarea); -DECLARE_PER_CPU(struct vmcs *, current_vmcs); +static DEFINE_PER_CPU(struct vmcs *, vmxarea); +static DEFINE_PER_CPU(struct vmcs *, current_vmcs);#ifdef __x86_64__#define HOST_IS_64 1
@@ -37,7 +37,7 @@ DECLARE_PER_CPU(struct vmcs *, current_v#define HOST_IS_64 0#endif -extern struct vmcs_descriptor { +static struct vmcs_descriptor { int size; int order; u32 revision_id;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 33/38 KVM: Make is_long_mode() an arch operation
In reply to Avi Kivitydrivers/kvm/kvm.h +1 -5
@@ -275,6 +275,7 @@ struct kvm_arch_ops { struct kvm_segment *var, int seg);void (*set_segment)(struct kvm_vcpu *vcpu,struct kvm_segment *var,int seg); +int (*is_long_mode)(struct kvm_vcpu *vcpu);void (*get_cs_db_l_bits)(struct kvm_vcpu *vcpu,int *db,int *l);void (*set_cr0)(struct kvm_vcpu *vcpu,unsigned long cr0); void (*set_cr0_no_modeswitch)(struct kvm_vcpu *vcpu,
@@ -411,11 +412,6 @@ static inline void vmcs_write32(unsignedvmcs_writel (field, value); } -static inline int is_long_mode (void ) -{ -return vmcs_read32 (VM_ENTRY_CONTROLS ) &VM_ENTRY_CONTROLS_IA32E_MASK ; -} -static inline int is_pae (struct kvm_vcpu *vcpu) {return vcpu->cr4 &CR4_PAE_MASK ;
drivers/kvm/kvm_main.c +2 -2
@@ -441,7 +441,7 @@ void set_cr4(struct kvm_vcpu *vcpu, unsireturn ; } -if (is_long_mode ()) { +if (kvm_arch_ops->is_long_mode (vcpu)) {if (!(cr4 &CR4_PAE_MASK )) {printk (KERN_DEBUG "set_cr4: #GP, clearing PAE while " "in long mode\n" );
@@ -468,7 +468,7 @@ EXPORT_SYMBOL_GPL(set_cr4);void set_cr3 (struct kvm_vcpu *vcpu,unsigned long cr3) { -if (is_long_mode ()) { +if (kvm_arch_ops->is_long_mode (vcpu)) {if ( cr3 &CR3_L_MODE_RESEVED_BITS ) {printk (KERN_DEBUG "set_cr3: #GP, reserved bits\n" );inject_gp (vcpu);
drivers/kvm/mmu.c +1 -1
@@ -589,7 +589,7 @@ static int init_kvm_mmu(struct kvm_vcpuif (!is_paging (vcpu))return nonpaging_init_context (vcpu); -else if (is_long_mode ()) +else if (kvm_arch_ops->is_long_mode (vcpu))return paging64_init_context (vcpu);else if (is_pae (vcpu))return paging32E_init_context (vcpu);
drivers/kvm/paging_tmpl.h +3 -3
@@ -70,7 +70,7 @@ static void FNAME(init_walker)(struct gu hpa =safe_gpa_to_hpa (vcpu, vcpu->cr3 &PT64_BASE_ADDR_MASK ); walker->table =kmap_atomic (pfn_to_page (hpa >>PAGE_SHIFT ),KM_USER0 ); -ASSERT ((!is_long_mode () &&is_pae (vcpu)) || +ASSERT ((!kvm_arch_ops->is_long_mode (vcpu) &&is_pae (vcpu)) || (vcpu->cr3 & ~(PAGE_MASK |CR3_FLAGS_MASK )) ==0 ); walker->table = (pt_element_t *)( (unsigned long)walker->table |
@@ -135,7 +135,7 @@ static pt_element_t *FNAME(fetch_guest)( (walker->table[index] &PT_PAGE_SIZE_MASK ) && (PTTYPE == 64 || is_pse(vcpu)))) return &walker->table[index]; -if (walker->level !=3 ||is_long_mode ()) +if (walker->level !=3 || kvm_arch_ops->is_long_mode (vcpu)) walker->inherited_ar &= walker->table[index]; paddr =safe_gpa_to_hpa (vcpu, walker->table[index] &PT_BASE_ADDR_MASK );kunmap_atomic (walker->table,KM_USER0 );
@@ -204,7 +204,7 @@ static u64 *FNAME(fetch)(struct kvm_vcpu shadow_addr =kvm_mmu_alloc_page (vcpu, shadow_ent);if (!VALID_PAGE (shadow_addr))return ERR_PTR (-ENOMEM ); -if (!is_long_mode () && level ==3 ) +if (!kvm_arch_ops->is_long_mode (vcpu) && level ==3 ) *shadow_ent = shadow_addr | (*guest_ent & (PT_PRESENT_MASK |PT_PWT_MASK |PT_PCD_MASK ));else {
drivers/kvm/vmx.c +6 -0
@@ -811,6 +811,11 @@ static void vmx_set_segment(struct kvm_vvmcs_write32 (sf->ar_bytes, ar); } +static int vmx_is_long_mode (struct kvm_vcpu *vcpu) +{ +return vmcs_read32 (VM_ENTRY_CONTROLS ) &VM_ENTRY_CONTROLS_IA32E_MASK ; +} +static void vmx_get_cs_db_l_bits (struct kvm_vcpu *vcpu,int *db,int *l) {u32 ar =vmcs_read32 (GUEST_CS_AR_BYTES );
@@ -1884,6 +1889,7 @@ static struct kvm_arch_ops vmx_arch_ops .get_segment_base = vmx_get_segment_base, .get_segment = vmx_get_segment, .set_segment = vmx_set_segment, + .is_long_mode = vmx_is_long_mode, .get_cs_db_l_bits = vmx_get_cs_db_l_bits, .set_cr0 = vmx_set_cr0, .set_cr0_no_modeswitch = vmx_set_cr0_no_modeswitch,
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 34/38 KVM: Use the tlb flush arch operation instead of an inline
In reply to Avi Kivitydrivers/kvm/kvm.h +0 -5
@@ -445,11 +445,6 @@ static inline int is_external_interrupt( == (INTR_TYPE_EXT_INTR | INTR_INFO_VALID_MASK); } -static inline void flush_guest_tlb (struct kvm_vcpu *vcpu) -{ -vmcs_writel (GUEST_CR3 ,vmcs_readl (GUEST_CR3 )); -} -static inline int memslot_id (struct kvm *kvm,struct kvm_memory_slot *slot) {return slot - kvm->memslots;
drivers/kvm/kvm_main.c +1 -1
@@ -775,7 +775,7 @@ static int kvm_dev_ioctl_get_dirty_log(sif (!vcpu)continue ; -flush_guest_tlb (vcpu); + kvm_arch_ops->flush_tlb (vcpu);vcpu_put (vcpu); } }
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 35/38 KVM: Remove guest_cpl()
In reply to Avi KivityThis was used only in debugging.
drivers/kvm/kvm.h +0 -5
@@ -422,11 +422,6 @@ static inline int is_pse(struct kvm_vcpureturn vcpu->cr4 &CR4_PSE_MASK ; } -static inline unsigned guest_cpl (void ) -{ -return vmcs_read16 (GUEST_CS_SELECTOR ) &SELECTOR_RPL_MASK ; -} -static inline int is_paging (struct kvm_vcpu *vcpu) {return vcpu->cr0 &CR0_PG_MASK ;
drivers/kvm/vmx.c +0 -8
@@ -1391,14 +1391,6 @@ static int handle_cr(struct kvm_vcpu *vcint cr;int reg; -#ifdef KVM_DEBUG -if (guest_cpl () !=0 ) { -vcpu_printf (vcpu,"%s: not supervisor\n" , __FUNCTION__); -inject_gp (vcpu); -return 1 ; - } -#endif - exit_qualification =vmcs_read64 (EXIT_QUALIFICATION ); cr = exit_qualification &15 ; reg = (exit_qualification >>8 ) &15 ;
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 36/38 KVM: Move vmcs accessors to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm.h +0 -27
@@ -377,9 +377,6 @@ int kvm_write_guest(struct kvm_vcpu *vcpunsigned long size, void *data); -void vmcs_writel (unsigned long field,unsigned long value); -unsigned long vmcs_readl (unsigned long field); -unsigned long segment_base (u16 selector);static inline struct page *_gfn_to_page (struct kvm *kvm,gfn_t gfn)
@@ -388,30 +385,6 @@ static inline struct page *_gfn_to_page(return (slot) ? slot->phys_mem[gfn - slot->base_gfn] :0 ; } -static inline u16 vmcs_read16 (unsigned long field) -{ -return vmcs_readl (field); -} - -static inline u32 vmcs_read32 (unsigned long field) -{ -return vmcs_readl (field); -} - -static inline u64 vmcs_read64 (unsigned long field) -{ -#ifdef __x86_64__ -return vmcs_readl (field); -#else -return vmcs_readl (field) | ((u64 )vmcs_readl (field+1 ) <<32 ); -#endif -} - -static inline void vmcs_write32 (unsigned long field,u32 value) -{ -vmcs_writel (field, value); -} -static inline int is_pae (struct kvm_vcpu *vcpu) {return vcpu->cr4 &CR4_PAE_MASK ;
drivers/kvm/kvm_main.c +0 -22
@@ -310,28 +310,6 @@ static int kvm_dev_release(struct inodereturn 0 ; } -unsigned long vmcs_readl (unsigned long field) -{ -unsigned long value; - - asm volatile (ASM_VMX_VMREAD_RDX_RAX - : "=a"(value) : "d"(field) : "cc"); - return value; -} -EXPORT_SYMBOL_GPL (vmcs_readl); - -void vmcs_writel (unsigned long field,unsigned long value) -{ -u8 error; - - asmvolatile (ASM_VMX_VMWRITE_RAX_RDX "; setna %0" - :"=q" (error) :"a" (value),"d" (field) :"cc" ); -if (error) -printk (KERN_ERR "vmwrite error: reg %lx value %lx (err %d)\n" , - field, value,vmcs_read32 (VM_INSTRUCTION_ERROR )); -} -EXPORT_SYMBOL_GPL (vmcs_writel); -static void inject_gp (struct kvm_vcpu *vcpu) { kvm_arch_ops->inject_gp (vcpu,0 );
drivers/kvm/kvm_vmx.h +0 -16
@@ -1,22 +1,6 @@#ifndef __KVM_VMX_H#define __KVM_VMX_H -static inline void vmcs_write16 (unsigned long field,u16 value) -{ -vmcs_writel (field, value); -} - -static inline void vmcs_write64 (unsigned long field,u64 value) -{ -#ifdef __x86_64__ -vmcs_writel (field, value); -#else -vmcs_writel (field, value); - asmvolatile ("" ); -vmcs_writel (field+1 , value >>32 ); -#endif -} -#ifdef __x86_64__/* * avoid save/load MSR_SYSCALL_MASK and MSR_LSTAR by std vt
drivers/kvm/vmx.c +60 -0
66 lines not on this page · raw message
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 37/38 KVM: Move vmx helper inlines to vmx.c
In reply to Avi Kivitydrivers/kvm/kvm.h +0 -13
@@ -400,19 +400,6 @@ static inline int is_paging(struct kvm_vreturn vcpu->cr0 &CR0_PG_MASK ; } -static inline int is_page_fault (u32 intr_info) -{ -return (intr_info & (INTR_INFO_INTR_TYPE_MASK |INTR_INFO_VECTOR_MASK | -INTR_INFO_VALID_MASK )) == - (INTR_TYPE_EXCEPTION |PF_VECTOR |INTR_INFO_VALID_MASK ); -} - -static inline int is_external_interrupt (u32 intr_info) -{ -return (intr_info & (INTR_INFO_INTR_TYPE_MASK |INTR_INFO_VALID_MASK )) - == (INTR_TYPE_EXT_INTR |INTR_INFO_VALID_MASK ); -} -static inline int memslot_id (struct kvm *kvm,struct kvm_memory_slot *slot) {return slot - kvm->memslots;
drivers/kvm/vmx.c +13 -0
@@ -77,6 +77,19 @@ static const u32 vmx_msr_index[] = {struct vmx_msr_entry *find_msr_entry (struct kvm_vcpu *vcpu,u32 msr); +static inline int is_page_fault (u32 intr_info) +{ +return (intr_info & (INTR_INFO_INTR_TYPE_MASK |INTR_INFO_VECTOR_MASK | +INTR_INFO_VALID_MASK )) == + (INTR_TYPE_EXCEPTION |PF_VECTOR |INTR_INFO_VALID_MASK ); +} + +static inline int is_external_interrupt (u32 intr_info) +{ +return (intr_info & (INTR_INFO_INTR_TYPE_MASK |INTR_INFO_VALID_MASK )) + == (INTR_TYPE_EXT_INTR |INTR_INFO_VALID_MASK ); +} +static void vmcs_clear (struct vmcs *vmcs) {u64 phys_addr =__pa (vmcs);
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
PATCH 38/38 KVM: Remove vmx includes from arch independent code
In reply to Avi Kivitydrivers/kvm/kvm_main.c +0 -2
@@ -35,8 +35,6 @@#include <linux/file.h> #include <asm/desc.h> -#include "vmx.h" -#include "kvm_vmx.h" #include "x86_emulate.h" MODULE_AUTHOR ("Qumranet" );
drivers/kvm/vmx.c +1 -1
@@ -16,9 +16,9 @@*/ #include "kvm.h" -#include <linux/module.h> #include "vmx.h" #include "kvm_vmx.h" +#include <linux/module.h> #include <linux/mm.h> #include <linux/highmem.h> #include <asm/io.h>
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV